Click here to Skip to main content
15,867,308 members
Articles / Multimedia / GDI+
Article

Multitab Color Picker

Rate me:
Please Sign up or sign in to vote.
4.60/5 (22 votes)
6 Jan 2006Zlib2 min read 78.9K   1.9K   37   12
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:

C#
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:

C#
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:

C#
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:

C#
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, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Software Developer (Senior)
Croatia Croatia
Graduated at the Faculty of Electrical Engineering and Computing, University of Zagreb (Croatia) and received M.Sc. degree in electronics. For several years he was research and lecturing assistant in the fields of solid state electronics and electronic circuits, published several scientific and professional papers, as well as a book "Physics of Semiconductor Devices - Solved Problems with Theory" (in Croatian).
During that work he gained interest in C++ programming language and have co-written "C++ Demystified" (in Croatian), 1st edition published in 1997, 2nd in 2001, 3rd in 2010, 4th in 2014.
After book publication, completely switched to software development, programming mostly in C++ and in C#.
In 2016 coauthored the book "Python for Curious" (in Croatian).

Comments and Discussions

 
GeneralMy vote of 5 Pin
BravoIT1-Oct-12 15:12
BravoIT1-Oct-12 15:12 
QuestionStandalone control? Pin
Richard Jones19-Jun-07 3:52
Richard Jones19-Jun-07 3:52 
AnswerRe: Standalone control? Pin
Julijan Sribar19-Jun-07 9:45
Julijan Sribar19-Jun-07 9:45 
GeneralRe: Standalone control? Pin
Richard Jones20-Jun-07 3:32
Richard Jones20-Jun-07 3:32 
GeneralRe: Standalone control? Pin
Julijan Sribar20-Jun-07 5:20
Julijan Sribar20-Jun-07 5:20 
Generalconverted to Net 2.0 okay, one minor question Pin
BillWoodruff12-Jan-06 1:20
professionalBillWoodruff12-Jan-06 1:20 
GeneralRe: converted to Net 2.0 okay, one minor question Pin
Julijan Sribar14-Jan-06 6:11
Julijan Sribar14-Jan-06 6:11 
GeneralVery cool Pin
Brian Pautsch10-Jan-06 4:23
Brian Pautsch10-Jan-06 4:23 
Generalexcellent work ! Pin
BillWoodruff9-Jan-06 20:00
professionalBillWoodruff9-Jan-06 20:00 
GeneralGood Article Pin
Paul Conrad7-Jan-06 18:05
professionalPaul Conrad7-Jan-06 18:05 
GeneralRe: Good Article Pin
Julijan Sribar14-Jan-06 5:58
Julijan Sribar14-Jan-06 5:58 
GeneralRe: Good Article Pin
Jeremy Falcon6-Jan-07 9:39
professionalJeremy Falcon6-Jan-07 9:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.