65.9K
CodeProject is changing. Read more.
Home

A Simple Paintbrush Color Picker

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.86/5 (3 votes)

Jan 24, 2005

1 min read

viewsIcon

47720

downloadIcon

670

A simple color picker like paintbrush color picker.

Introduction

The control is very simple but I think it is helpful for beginners in C# programming, especially .NET UserControl programming.

Behaviors

Just like Paintbrush color picker, our color picker must have the following features:

  • An area which shows the current selected brush and pen color.
  • Provides some predefined colors which is divided into two rows. The first row is darker than the second row.
  • User would use the left mouse button to select pen color and right mouse button for brush color.
  • When the user double clicks on a specified color cell, the application would ask the user which color they want to use by using the standard color picker dialog.
  • And the last one, this control should have an event for notifying parent about the changing of brush and pen color.

Implement

First, we should create a new user control which contains several labels as Color Cell that you will see when you view the control in design time. After that, we should have a way to store the predefined colors and the selected brush and pen color. The example given below explains in detail how this can be done:

private const int TotalColors = 16;
private Color[] _Colors = new Color[TotalColors];
private int _selPenColor = 0;
private int _selBrushColor = 1;
public Color PenColor
{
    get { return this._Colors[_selPenColor];}
    set 
    {
        this._Colors[0] = value;
        this._selPenColor = 0;
    }
}
public Color BrushColor
{
    get {return this._Colors[_selBrushColor];}
    set
    {
        this._Colors[TotalColors/2] = value;
        this._selBrushColor = TotalColors/2;
    }
}

In the next step, we should have some functions that should take care of drawing:

private void DrawSelectedColor(Graphics graph, Rectangle rect, 
                                Color clrPen, Color clrBrush)
{
    Brush brushBackground = new SolidBrush(this.BackColor);
    Brush penBrush = new SolidBrush(clrPen);
    Brush brushBrush = new SolidBrush(clrBrush);

    Point ptCenter = new Point(rect.Left + rect.Width/2, 
                              rect.Top + rect.Height/2);
    int cellWidth = 16;
    int cellHeight = 16;

    int XMargin = 4;
    int YMargin = 4;

    Rectangle rectPen = new Rectangle(XMargin, YMargin, 
                                cellWidth, cellHeight);
    Rectangle rectBrush = new Rectangle(rect.Right-XMargin-cellWidth, 
              rect.Bottom-YMargin-cellHeight, cellWidth, cellHeight);

    // clear background
    graph.FillRectangle(brushBackground, rect);

    // draw selected colors
    graph.FillRectangle(brushBrush, rectBrush);
    ControlPaint.DrawBorder3D(graph, rectBrush, Border3DStyle.Raised);

    graph.FillRectangle(penBrush, rectPen);
    ControlPaint.DrawBorder3D(graph, rectPen, Border3DStyle.Raised);
    
    // draw border 3D
    ControlPaint.DrawBorder3D(graph, rect, Border3DStyle.Sunken);

    penBrush.Dispose();
    brushBrush.Dispose();
    brushBackground.Dispose();
}
private void DrawColor(Graphics graph, Rectangle rect, Color color)
{
    Brush brush = new SolidBrush(color);
    graph.FillRectangle(brush, rect);
    
    ControlPaint.DrawBorder3D(graph, rect, Border3DStyle.SunkenOuter);
    brush.Dispose();
}

And just attach the implemented function to the standard drawing routing of the owner:

private void ColorButton_Paint(object sender, PaintEventArgs e)
{
    if (sender is Label)
    {
        Label btn = sender as Label;
        int colorID = Int32.Parse(btn.Tag.ToString());
        DrawColor(e.Graphics, btn.DisplayRectangle, this._Colors[colorID]);
    }            
}
private void SelectColorButton_Paint(object sender, PaintEventArgs e)
{
    DrawSelectedColor(e.Graphics, btnSelectedColors.DisplayRectangle, 
                                     this.PenColor, this.BrushColor);
}

As I mentioned before, we should have a delegate to notify the container about the changing of selected pen and brush color.

public event EventHandler    PenColorChanged = null;
public event EventHandler    BrushColorChanged = null;

...........

private void OnSelectedBrushColorChanged()
{

    if (this.BrushColorChanged != null)
        this.BrushColorChanged(this, new System.EventArgs());
}

private void OnSelectedPenColorChanged()
{
    if (this.PenColorChanged != null)
        this.PenColorChanged(this, new System.EventArgs());
}

And the last one, we should handle the selecting operation of end user:

private void ColorButton_MouseDown(object sender, MouseEventArgs e)
{            
    if (!(sender is Label)) return;
    Label btn = sender as Label;
    int colorID = Int32.Parse(btn.Tag.ToString());
        
    if (e.Button == MouseButtons.Left)
        this.SelectPenColorID = colorID;
    else if (e.Button == MouseButtons.Right)
        this.SelectedBrushColorID = colorID;
    btnSelectedColors.Invalidate();
}
private void ColorButton_DoubleClick(object sender, System.EventArgs e)
{
    if (!(sender is Label)) return;
    Label btn = sender as Label;
    int colorID = Int32.Parse(btn.Tag.ToString());

    ColorDialog dlg = new ColorDialog();
    dlg.Color = this._Colors[colorID];
    dlg.FullOpen = false;
    dlg.SolidColorOnly = true;
    if (dlg.ShowDialog(this) == DialogResult.OK)
    {
        this._Colors[colorID] = dlg.Color;
        this.Refresh();
    }
}

And now, you can build your project and test your new Paintbrush - like Color Picker.