Click here to Skip to main content
Click here to Skip to main content

MS Office Style Colour-Picker Dialog

, 14 Jan 2003
Rate this:
Please Sign up or sign in to vote.
A clone of the font color dialog like found at Microsoft Word.
<!-- Download Links -->

Sample Image - color_picker.gif

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 in the Microsoft Office suite (for choosing the font color) as a source of inspiration. I used exactly the same palette of 40 colors and almost 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 exciting. It should be self-explaining. The control is a form with 40 square little 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).

The demo project consists of three classes:

  • ColorPaletteDialog,
  • ColorButton and
  • MainForm
The code on this pages shows only the ColorPaletteDialog class, which is the most interesting. The other two can be found in the distributable archive, along with a compiled *.exe.

The ColorButton class (derived from the Button class) is used in order to display the last chosen color on its center. You can use the Color attribute of an ordinary button too, but I wanted to have a border around it and the little arrow, indicating further options, like found at the color picker for the color schemes of the Windows desktop. For the color display a new attribute "CenterColor" was added to the derived class.

The example form features three ColorButton instances, using different sizes and different styles (popup, flat and normal). The ColorButton_Click event handler checks which button is the sender of the message and acts accordingly. A standard color dialog is called from the "More colors..." button, as usual.

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;
        cancelButton.DialogResult = DialogResult.Cancel;
        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;
        if(colDialog.ShowDialog() == DialogResult.OK)
        {
               selectedColor = colDialog.Color;
               DialogResult = DialogResult.OK;
        }
        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;
        DialogResult = DialogResult.OK;
        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.

The project was developed with the free .NET IDE SharpDevelop (www.icsharpcode.net).
Visit my Homepage www.programming.de for more example code.

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

About the Author

Johannes Wallroth
Web Developer
Germany Germany
No Biography provided

Comments and Discussions

 
GeneralToolbar Button Pinmemberrocketman22118-Dec-10 13:31 
GeneralFocus Problems... PinmemberFreewareFire26-Apr-06 4:58 
GeneralRe: Focus Problems... PinmemberJohannes Wallroth27-Apr-06 5:29 
AnswerRe: Focus Problems... PinmemberFreewareFire27-Apr-06 12:31 
GeneralRe: Focus Problems... PinmemberJohannes Wallroth27-Apr-06 21:10 
GeneralRe: Focus Problems... PinmemberFreewareFire28-Apr-06 11:25 
GeneralAwesome! PinmemberdzCepheus2-Jan-06 11:32 
GeneralRe: Awesome! Pinmemberloid grey manuel26-Aug-10 21:11 
QuestionDo you have VC++/ MFC code for this ? Pinmemberakulkarni23-Feb-04 2:06 
Questioncache those rectangles ? PinsussBill Woodruff11-Dec-02 1:11 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140709.1 | Last Updated 15 Jan 2003
Article Copyright 2002 by Johannes Wallroth
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid