Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Multitab Color Picker

0.00/5 (No votes)
6 Jan 2006 1  
Another color picker control in C#.

Sample Image

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here