CustomControl: Colors ComboBox
Allows your users to select only colors included in your list

Introduction
This is a custom control, a useful, good alternative to standard ColorDialog from C# standard controls (dialogs). You can personalize the color list adding only the colors you want. The visual aspect, I hope, is professional.
Let's start!
I use Visual C# Express edition. Open a new C# project (Windows application). Right click on properties window and chose "Add new Item" from the menu that appears.
The default item to add is a new class. You can change the file's name (default is class1.cs) or not (as you prefer).
We need to use the following namespaces...
using System;
using System.Drawing;
using System.Windows.Forms;
...to have access to all we need to build this control.
The full code for this control is as follows:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CustomColoredComboBox
{
class ColoredComboBox : ComboBox
{
//the default colors from list
private string[] arr_MyColors = { "Black", "Red", "Blue", "Green" };
protected int inMargin;
protected int boxWidth;
private Color c;
//public properties to interact with control from properties window
public string[] MyColors
{
get { return arr_MyColors; }
set
{
int col_numbers = value.Length;
arr_MyColors = new string[col_numbers];
for (int i = 0; i < col_numbers; i++)
arr_MyColors[i] = value[i];
this.Items.Clear();
InitCombo();
}
}
public ColoredComboBox() //constructor
{
DrawMode = DrawMode.OwnerDrawFixed;
DropDownStyle = ComboBoxStyle.DropDownList;
inMargin = 2;
boxWidth = 3;
BeginUpdate();
InitCombo();
EndUpdate();
}
private void InitCombo() //add items
{
if (arr_MyColors == null) return;
foreach (string color in arr_MyColors)
{
try
{
if (Color.FromName(color).IsKnownColor)
this.Items.Add(color);
}
catch
{
throw new Exception("Invalid Color Name: " + color);
}
}
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
if ((e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit)
e.DrawBackground();
Graphics g = e.Graphics;
if (e.Index == -1) //if index is -1 do nothing
return;
c = Color.FromName((string)base.Items[e.Index]);
//the color rectangle
g.FillRectangle(new SolidBrush(c), e.Bounds.X + this.inMargin, e.Bounds.Y +
this.inMargin, e.Bounds.Width / this.boxWidth - 2 * this.inMargin,
e.Bounds.Height - 2 * this.inMargin);
//draw border around color rectangle
g.DrawRectangle(Pens.Black, e.Bounds.X + this.inMargin,
e.Bounds.Y + this.inMargin, e.Bounds.Width / this.boxWidth -
2 * this.inMargin, e.Bounds.Height - 2 * this.inMargin);
//draw strings
g.DrawString(c.Name, e.Font, new SolidBrush(ForeColor),
(float)(e.Bounds.Width / this.boxWidth + 5 * this.inMargin),
(float)e.Bounds.Y);
}
}
}
The code is simple.arr_MyColors
is the initial color list and it can be changed from Properties Panel.
This is possible because of the following public
property:
//public property to interact with control from properties window
public string[] MyColors
{
get { return arr_MyColors; }
set
{
int col_numbers = value.Length;
arr_MyColors = new string[col_numbers];
for (int i = 0; i < col_numbers; i++)
arr_MyColors[i] = value[i];
this.Items.Clear();
InitCombo();
}
}
The most important function in the constructor is InitCombo()
. This function adds Items to the ComboBox
list (as you can see, our control is a custom ComboBox
). Inside this function, I verify if the color that the user tries to add to the list is KnownColor
- and if it is, I add this color. This is important, because if someone adds (by mistake, spelling mistakes) a wrong name, this color will not appear correctly inside the list.
The hard work is done by protected override void OnDrawItem(DrawItemEventArgs e)
. The control box is drawn inside this function.
As you can see, I have three drawing operations there:
- Drawing the color rectangle
- Drawing the border around the color rectangle
- Drawing the
string
(this is the name of color)
This is all (I know... it can be improved).
How To Use It?
Simple. Return to the form that C# Express opened for you when you started to work, open the toolbox panel (Ctrl+W, X) and you'll see the control we have just created at the top of the controls list. Just drag it in your form. Open the Properties panel (Ctrl+W,P) and set up all the properties you need for this control.
Remember that the color list is accessible only from MyColors
properties, and not from Items (we clear this in InitCombo()
function).
I have already uploaded a program that exemplifies the usage of this custom control and the way in which the color selected by the user can be used.
This custom control can be improved and the code that I posted here is just a code that I needed for one of my applications. Any suggestion for improvement is welcome.
History
- 16th January, 2007: Initial post