In the Visual Studio forms designer, the property grids allow you to pick a colour from a drop-down box.
I was a little surprised to find that there was no existing control that already had this functionality.
A search on the internet turned up a number of results, but they all seemed to have over complicated the problem, and were hundreds of lines of code or they used the tool-strip drop down.
This little control extension sets the
OwnerDrawFixed
property to
true
, this activates the
DrawItem
event and the
OnDrawItem
method (if you override the
OnDrawItem
method, but don't set the control to be
OwnerDrawFixed
, then
OnDrawItem
is never invoked, and the
DrawItem
event is never called).
The
OnDrawItem
method is overridden, and if the item that is being drawn is a
System.Drawing.Color struct
, then the method manufactures a
new DrawItemEventArgs
object, with the
BackgroundColor
property set to the current item colour.
The
DrawItem
event is handled, and in this event we simply duplicate what the standard event did, which is to draw the background and the text value over it.
class ColourCombo : ComboBox
{
public ColourCombo()
: base()
{
this.DrawMode = DrawMode.OwnerDrawFixed;
this.DrawItem += new DrawItemEventHandler(ColourCombo_DrawItem);
}
void ColourCombo_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.Graphics.DrawString(((ComboBox)sender).Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds);
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
this.BackColor = this.SelectedColour;
if (this.BackColor.GetBrightness() < 0.5)
this.ForeColor = Color.White;
else
this.ForeColor = Color.Black;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
var item = this.Items[e.Index];
if (item is Color)
{
DrawItemEventArgs de = new DrawItemEventArgs(e.Graphics, e.Font, e.Bounds, e.Index, e.State, e.ForeColor, (Color)item);
base.OnDrawItem(de);
}
else
base.OnDrawItem(e);
}
public void LoadRainbow()
{
this.Items.Add(Color.Red);
this.Items.Add(Color.Orange);
this.Items.Add(Color.Yellow);
this.Items.Add(Color.Green);
this.Items.Add(Color.Blue);
this.Items.Add(Color.Indigo);
this.Items.Add(Color.Violet);
}
public void LoadDarkRainbow()
{
this.Items.Add(Color.DarkRed);
this.Items.Add(Color.DarkOrange);
this.Items.Add(Color.Brown);
this.Items.Add(Color.DarkGreen);
this.Items.Add(Color.DarkBlue);
this.Items.Add(Color.DarkMagenta);
this.Items.Add(Color.DarkViolet);
}
public Color SelectedColour
{
get
{
if (SelectedItem != null && SelectedItem is Color)
return (Color)SelectedItem;
else
return this.BackColor;
}
set
{
this.SelectedItem = value;
}
}
}