Introduction
The intention was to create a control that would mimic the color picker found in Visual Studio. It consists of three tabs allowing the user to select one of predefined, named, or system colors, or to mix his/her own custom color.
Background
The control is derived from TabControl
. It contains three tab pages:
- Named page with a custom drawn listbox with named colors,
- System page with a custom drawn listbox with system colors, and
- Custom tab, which contains a user control that allows a user to define a color with custom alpha, red, green, and blue components.
When the user selects a color, the ColorSelected
event is fired. The ColorSelectedEventArgs
object contains the selected color.
A custom color control is a user control that contains trackbars for each component and a preview box. Since it is possible to set a non-uniform background and paint the box with the selected color partially, the user can clearly observe the color transparency effect.
Using the code
The control can be easily embedded into a dialog by adding the corresponding MultiTabColorPicker.dll into the list of references and including the System.Windows.Forms.ColorPicker
namespace in which the control has has been defined. In order to detect color selection changes, the user just has to attach to the ColorSelected
event. This event is made visible (and set as default) in the events of the property grid of the control. The ColorSelected
event and the corresponding ColorSelectedEventArgs
are defined like:
public class ColorSelectedEventArgs : System.EventArgs {
public ColorSelectedEventArgs(Color colorSelected) {
ColorSelected = colorSelected;
}
public readonly Color ColorSelected;
}
public delegate void ColorSelectedEventHandler(object sender,
ColorSelectedEventArgs e);
So, on the client side, it is only necessary to get the ColorSelected
field from ColorSelectedEventArgs
:
m_colorPicker.ColorSelected +=
new ColorSelectedEventHandler(this.ColorSelected);
private void ColorSelected(object sender, ColorSelectedEventArgs e) {
m_labelSample.ForeColor = e.ColorSelected;
}
The control also exposes some additional properties:
CustomColorSampleBackground
which defines how the background of the custom color preview control is painted. It can be set to one of several predefined values: Uniform
, ShadesOfControl
, GradientGray
, and GradientColor
;
CustomColorSamplePosition
defines which part of the box is painted with the selected custom color. It can be set to Entire
, Top
, Middle
, or Bottom
.
NameColorsSortOrder
defines the order by which colors in the named colors list is sorted: HSB
, Alphabetical
, or None
.
Points of Interest
The most challenging part was to obtain the list of colors in the exact same order as in Visual Studio. The list of all colors is created by means of reflection:
Type color =(typeof(Color));
PropertyInfo[] propertyInfos =
color.GetProperties(BindingFlags.Public | BindingFlags.Static);
ArrayList colors = new ArrayList();
foreach (PropertyInfo pi in propertyInfos) {
if (pi.PropertyType.Equals(typeof(Color))) {
Color c = (Color)pi.GetValue(color, null);
colors.Add(c);
}
}
The list is then sorted using the HSB_ColorComparer
class:
internal class HSB_ColorComparer : IComparer {
public int Compare(Color c1, Color c2) {
int alphaDiff = c1.A - c2.A;
float hueDiff = c1.GetHue() - c2.GetHue();
float saturationDiff = c1.GetSaturation() - c2.GetSaturation();
float brightnessDiff = c1.GetBrightness() - c2.GetBrightness();
return (int)(((alphaDiff * 360 + hueDiff +
saturationDiff) * 255 + brightnessDiff) * 255);
}
int IComparer.Compare(object obj1, object obj2) {
return Compare((Color)obj1, (Color)obj2);
}
}
This sorting produces a list that is almost identical to the one in Visual Studio, except for the three items being misplaced. Moreover, a NameColorComparer
class is provided for sorting the colors alphabetically by their names.
The demo project also shows how to embed the control into a non-modal form that acts as a popup window. This popup window is automatically closed (actually hidden) when it loses focus, or when the user selects a color or presses the ESC button.
History
- Ver. 1.0 - initial release, submitted January 2, 2006.