MS Office Style Color Picker Dialog


MS-Word Style ColorPicker Dialog

Introduction

For a project I'm working on I needed something more stylish than the standard color dialog which comes with .NET, so I decided to make a color picker dialog of my own. I used the one found at Microsoft Office (for choosing the font color) as a souce of inspiration (in fact, I shamelessly copied it) - I used exactly the same palette of 40 colors and the same "look and feel" - only the size and distance of the little color panels is a little different in my version.

Using the code

The code for the color dialog is very straightforward and offers nothing unusual. It has only about 200 lines of code and should be self-explaining. The control is a form with 40 small panel controls, which have event handlers for mouse messages attached to them. The constructor receives the coordinates of the point it is supposed to appear at as arguments (usually the calling button of the container form). When closed, the color dialog returns the chosen color. The dialog can alternatively be closed by hitting Escape or Enter (by using an "invisible" Escape button). In my small demo program the background color changes according to the chosen color. A standard color dialog is called from the "More colors..." button.

public class ColorPaletteDialog : Form
{
byte max = 40;
Panel[] panel =
new Panel[40];
Color[] color =
new Color[40]
{
//row 1
Color.FromArgb(0,0,0), Color.FromArgb(153,51,0),Color.FromArgb(51,51,0), Color.FromArgb(0,51,0),Color.FromArgb(0,51,102), Color.FromArgb(0,0,128),

Color.FromArgb(51,51,153), Color.FromArgb(51,51,51),
//row 2
Color.FromArgb(128,0,0), Color.FromArgb(255,102,0),
Color.FromArgb(128,128,0), Color.FromArgb(0,128,0),
Color.FromArgb(0,128,128), Color.FromArgb(0,0,255),
Color.FromArgb(102,102,153), Color.FromArgb(128,128,128),
//row 3
Color.FromArgb(255,0,0), Color.FromArgb(255,153,0),
Color.FromArgb(153,204,0), Color.FromArgb(51,153,102),
Color.FromArgb(51,204,204), Color.FromArgb(51,102,255),
Color.FromArgb(128,0,128), Color.FromArgb(153,153,153),
//row 4
Color.FromArgb(255,0,255), Color.FromArgb(255,204,0),
Color.FromArgb(255,255,0), Color.FromArgb(0,255,0),
Color.FromArgb(0,255,255), Color.FromArgb(0,204,255),
Color.FromArgb(153,51,102), Color.FromArgb(192,192,192),
//row 5
Color.FromArgb(255,153,204), Color.FromArgb(255,204,153),
Color.FromArgb(255,255,153), Color.FromArgb(204,255,204),
Color.FromArgb(204,255,255), Color.FromArgb(153,204,255),
Color.FromArgb(204,153,255), Color.FromArgb(255,255,255)
};
string[] colorName = new string[40]
{
"Black", "Brown", "Olive Green", "Dark Green", "Dark Teal",
"Dark Blue", "Indigo", "Gray-80%","Dark Red", "Orange", "Dark Yellow", "Green", "Teal", "Blue",

"Blue-Gray", "Gray-50%","Red", "Light Orange", "Lime", "Sea Green", "Aqua", "Light Blue", Violet", "Gray-40%",

"Pink", "Gold", "Yellow", "Bright Green", "Turquoise", "Sky Blue","Plum", "Gray-25%","Rose", "Tan", "Light Yellow", "Light Green", "Light Turquoise", "Pale Blue", "Lavender", "White"
};
Button moreColorsButton =
new Button();
Button cancelButton =
new Button();
Color selectedColor;
public ColorPaletteDialog(int x, int y)
{
Size =
new Size(158, 132);
FormBorderStyle = FormBorderStyle.FixedDialog;
MinimizeBox = MaximizeBox = ControlBox =
false;
ShowInTaskbar =
false;
CenterToScreen();
Location =
new Point(x, y);
BuildPalette();
moreColorsButton.Text = "More colors ...";
moreColorsButton.Size =
new Size(142, 22);
moreColorsButton.Location =
new Point(5, 99);
moreColorsButton.Click +=
new EventHandler(moreColorsButton_Click);
moreColorsButton.FlatStyle = FlatStyle.Popup;
Controls.Add(moreColorsButton);
//"invisible" button to cancel at Escape
cancelButton.Size = new Size(5, 5);
cancelButton.Location =
new Point(-10, -10);
cancelButton.Click +=
new EventHandler(cancelButton_Click);
Controls.Add(cancelButton);
cancelButton.TabIndex = 0;
this.CancelButton = cancelButton;
}
public Color Color
{
get {return selectedColor;}
}
void BuildPalette()
{
byte pwidth = 16;
byte pheight = 16;
byte pdistance = 2;
byte border = 5;
int x = border, y = border;
ToolTip toolTip =
new ToolTip();
for(int i = 0; i < max; i++)
{
panel[i] =
new Panel();
panel[i].Height = pwidth;
panel[i].Width = pheight;
panel[i].Location =
new Point(x, y);
toolTip.SetToolTip(panel[i], colorName[i]);
this.Controls.Add(panel[i]);
if(x < ( 7 * (pwidth + pdistance)))
x += pwidth + pdistance;
else
{
x = border;
y += pheight + pdistance;
}
panel[i].BackColor = color[i];
panel[i].MouseEnter +=
new EventHandler(OnMouseEnterPanel);
panel[i].MouseLeave +=
new EventHandler(OnMouseLeavePanel);
panel[i].MouseDown +=
new MouseEventHandler(OnMouseDownPanel);
panel[i].MouseUp +=
new MouseEventHandler(OnMouseUpPanel);
panel[i].Paint +=
new PaintEventHandler(OnPanelPaint);
}}

void moreColorsButton_Click(object sender, System.EventArgs e)
{
ColorDialog colDialog =
new ColorDialog();
colDialog.FullOpen =
true;
colDialog.ShowDialog();
selectedColor = colDialog.Color;
colDialog.Dispose();
Close();
}
void cancelButton_Click(object sender, System.EventArgs e)
{
Close();
}
void OnMouseEnterPanel(object sender, EventArgs e)
{
DrawPanel(sender, 1);
}
void OnMouseLeavePanel(object sender, EventArgs e)
{
DrawPanel(sender, 0);
}
void OnMouseDownPanel(object sender, MouseEventArgs e)
{
DrawPanel(sender, 2);
}
void OnMouseUpPanel(object sender, MouseEventArgs e)
{
Panel panel = (Panel)sender;
selectedColor = panel.BackColor;
Close();
}
void DrawPanel(object sender, byte state)
{
Panel panel = (Panel)sender;
Graphics g = panel.CreateGraphics();
Pen pen1, pen2;
if(state == 1) //mouse over
{
pen1 =
new Pen( SystemColors.ControlLightLight );
pen2 =
new Pen( SystemColors. ControlDarkDark);
}
else if(state == 2) //clicked
{
pen1 =
new Pen( SystemColors.ControlDarkDark );
pen2 =
new Pen( SystemColors.ControlLightLight );
}
else //neutral
{
pen1 =
new Pen( SystemColors.ControlDark );
pen2 =
new Pen( SystemColors.ControlDark );
}
Rectangle r = panel.ClientRectangle;
Point p1 =
new Point( r.Left, r.Top ); //top left
Point p2 = new Point( r.Right -1, r.Top ); //top right
Point p3 = new Point( r.Left, r.Bottom -1 ); //bottom left
Point p4 = new Point( r.Right -1, r.Bottom -1 ); //bottom right
g.DrawLine( pen1, p1, p2 );
g.DrawLine( pen1, p1, p3 );
g.DrawLine( pen2, p2, p4 );
g.DrawLine( pen2, p3, p4 );
}
void OnPanelPaint(Object sender, PaintEventArgs e)
{
DrawPanel(sender, 0);
}
}

Points of Interest

The little panels show the name of the selected color under the curser inside a tooltip. They also change their appearance, when the mouse hovers over them or clicks them. In order to do this, the Paint method for the panel is overloaded and we draw the borders of the panel ourselves (using System colors), dependant of the state of the mouse.