Skip to content

Instantly share code, notes, and snippets.

@CamelCaseName
Created July 24, 2023 18:17
Show Gist options
  • Save CamelCaseName/ddcc4f71649fa703e0fa517b2e759900 to your computer and use it in GitHub Desktop.
Save CamelCaseName/ddcc4f71649fa703e0fa517b2e759900 to your computer and use it in GitHub Desktop.
c# WinForms ComboBox where you can color some fields in a different color
using System;
using System.Drawing;
using System.Linq;
using System.Runtime.Versioning;
using System.Windows.Forms;
namespace CustomComponents
{
[SupportedOSPlatform("windows")]
internal sealed class ColoredDropDown : ComboBox
{
private int[] coloredIndices;
public Color SpecialIndexBackColor
{
get
{
return _specialIndexBackColor;
}
set
{
_specialIndexBackColor = value;
SpecialBackgroundBrush.Color = _specialIndexBackColor;
}
}
private Color _specialIndexBackColor = Color.MediumSeaGreen;
private readonly Pen BorderPen = new(SystemColors.Window);
private readonly Pen BlackPen = new(SystemColors.MenuText);
private readonly SolidBrush BlackBrush = new(SystemColors.MenuText);
private readonly SolidBrush BackgroundBrush = new(SystemColors.ScrollBar);
private readonly SolidBrush Borderbrush = new(SystemColors.Window);
private readonly SolidBrush SpecialBackgroundBrush = new(Color.MediumSeaGreen);
private readonly SolidBrush HighlightBrush = new(SystemColors.MenuHighlight);
public ColoredDropDown(int[] coloredIndices)
{
this.coloredIndices = coloredIndices;
SetStyle(ControlStyles.UserPaint, true);
DrawMode = DrawMode.OwnerDrawFixed;
}
public ColoredDropDown(int length) : this(new int[length]) { }
public ColoredDropDown() : this(Array.Empty<int>()) { }
public void SetColoredIndices(int[] indices)
{
coloredIndices = indices;
}
public void AddIndex(int index)
{
var newArray = new int[coloredIndices.Length + 1];
coloredIndices.CopyTo(newArray, 0);
newArray[^1] = index;
coloredIndices = newArray;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (e == null) return;
base.OnDrawItem(e);
//true when we hover over the item
if (e.State.HasFlag(DrawItemState.Focus))
{
e.Graphics.FillRectangle(HighlightBrush, e.Bounds);
}
else
{
if (coloredIndices.Contains(e.Index))
{
e.Graphics.FillRectangle(SpecialBackgroundBrush, e.Bounds);
}
else
{
//overdraw native drawing as its wrong lol
e.Graphics.FillRectangle(BackgroundBrush, e.Bounds);
}
}
if (e.Index > -1)
TextRenderer.DrawText(e.Graphics, Items[e.Index].ToString(), Font, new Rectangle(e.Bounds.X + 1, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height), SystemColors.MenuText, TextFormatFlags.Left);
}
protected override void OnPaint(PaintEventArgs e)
{
if (e == null) return;
base.OnPaint(e);
var h = Height;
var w = Width;
e.Graphics.DrawLine(BlackPen, new Point(0, h - 1), new Point(w, h - 1));
e.Graphics.DrawRectangle(BorderPen, new Rectangle(1, 1, w - 3, h - 4));
e.Graphics.FillRectangle(BackgroundBrush, new Rectangle(2, 2, w - 5, h - 6));
e.Graphics.FillRectangle(Borderbrush, new Rectangle(w - 18, 2, 16, h - 5));
e.Graphics.FillPolygon(BlackBrush, new Point[3] { new Point(w - 12, h - 14), new Point(w - 7, h - 14), new Point(w - 10, h - 11) });
TextRenderer.DrawText(e.Graphics, Text, Font, new Rectangle(1, 4, w, h - 4), ForeColor, TextFormatFlags.Left);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment