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

WPF Color Picker Like Office 2007

0.00/5 (No votes)
17 Jan 2010 1  
A simple to use Color Picker with advanced color palette for WPF Applications with look and feel of Office 2007 color picker
main.JPG >

Introduction

Recently, I was working on a WPF application which required a color picker for setting colors of various graph elements within the application. At first, this seemed like a five minute task for me as I was quite confident that I would get one for free on the internet. I was quite right until I was told that it should have a look and feel like that of Office 2007 color picker. Thus I built my own and here it is.

Features

The Color picker has the following features:

  • Choose color from a predefined list of colors
  • Choose custom color from a Color palette
  • Adjust the opacity of the selected color using a slider in custom color selection mode
  • Ease of use anywhere within a WPF application with a single bindable property for the selected color.

Implementation

The source code supplied is very much self explanatory and easy to understand. So I will highlight the points of interest. Let's begin with the how to use it in our application.

Basically the control has three files, so I have packaged it in a DLL.

<CustomWPFColorPicker:ColorPickerControlView x:Name="ForeColorPicker" />

The Control has a dependency property "CurrentColor" which gets updated when a color is picked from the picker either from the predefined list of colors or the advanced color palette.

public static DependencyProperty CurrentColorProperty = 
DependencyProperty.Register("CurrentColor", typeof(SolidColorBrush),
typeof(ColorPickerControlView), new PropertyMetadata(Brushes.Black)); 

The picker is a ToggleButton with little style edited to show the CurrentColor inside <border>. A Popup holds the predefined colors as in Office 2007. These are a set of buttons each representing a color via the command parameter.

<Button Click="Button_Click"  Style="{StaticResource ColorButtonStyleFirstRow}"
Command="{x:Static CustomWPFColorPicker:ColorPickerControlView.SelectColorCommand}" 
CommandParameter="#FFFFFF" Margin="3,4,3,4" Background="#FFFFFF" />

1.JPG

The "More Colors" button is used to open a model dialog containing the Advanced Picker where a user can select a color from a color palette with the mouse.

2.JPG

The color palette is a JPG image from which 4 bits are read during mousedown event, containing the colors for ARGB.

private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                var cb = new CroppedBitmap((BitmapSource)
		(((Image)e.Source).Source), new Int32Rect
		((int)Mouse.GetPosition(e.Source as Image).X, 
		(int)Mouse.GetPosition(e.Source as Image).Y, 1, 1));
                _pixels = new byte[4];
                try
                {
                    cb.CopyPixels(_pixels, 4, 0);
                    UpdateCurrentColor();
                    UpdateMarkerPosition();
                }
                catch
                {
                }
                UpdateSlider();
            }
            catch (Exception)
            {
            }
        }

Using these bits, the color is updated:

private void UpdateCurrentColor()
        {
            CurrentColor = Color.FromRgb(_pixels[2], _pixels[1], _pixels[0]);
            currentColorBorder.Background = 
	     new SolidColorBrush(Color.FromRgb(_pixels[2], _pixels[1], _pixels[0]));
            brightnessSlider.Value = 0.5;
            SelectedCurrentColor = new SolidColorBrush(CurrentColor);
        }

3.JPG

A slider is used to adjust the color value in order to let the user get more shades of the color selected from white to black. I have edited the style of the default WPF slider control to get the look that you see in the demo. Its background reflects the color shades that the users will get when they change the value. For achieving this, I have used a LinearGradientBrush which has 3 GradientStop at point 0, 0.5 and 1. At zero the color is white, at 0.5 the color is the selected color and at 1 it is black.

<LinearGradientBrush x:Key="BrightnessGradient" StartPoint="0,1" EndPoint="0,0" 
        ColorInterpolationMode="ScRgbLinearInterpolation">
            <GradientStop Offset="0" Color="sc# 1, 0,0,0" />
            <GradientStop Offset="0.5" Color="sc# 1, 0.5,0.5,0.5" />
            <GradientStop Offset="1" Color="sc# 1, 1,1,1" />
        </LinearGradientBrush>

As the slider value is changed, I calculate the color value based on the value of the slider. There are two special cases to consider here. When the slider value is nearing 0, the color should near more to White. When the slider value is nearing 1, it should near to Black. At 0 the color becomes white and at 1 it's Black. For this, I have devised an efficient algorithm which is very simple to understand. Note that here I am not simply changing the alpha value of the color, but calculating shades of the color from white to black with the selected color and the color whose shade is being adjusted.

void BrightnessSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (_pixels == null)
            {
                _pixels = new byte[3];
                _pixels[2] = CurrentColor.R;
                _pixels[1] = CurrentColor.G;
                _pixels[0] = CurrentColor.B;
            }

            var nc = Color.FromRgb(_pixels[2], _pixels[1], _pixels[0]);
            var f = (float)e.NewValue;
            float r, g, b;
            const float a = 1;

            if (f >= 0.5f)
            {
                r = nc.ScR + (1 - nc.ScR) * (f - 0.5f) * 2;
                g = nc.ScG + (1 - nc.ScG) * (f - 0.5f) * 2;
                b = nc.ScB + (1 - nc.ScB) * (f - 0.5f) * 2;
            }
            else
            {
                r = nc.ScR * f * 2;
                g = nc.ScG * f * 2;
                b = nc.ScB * f * 2;
            }

            CurrentColor = Color.FromScRgb(a, r, g, b);
            currentColorBorder.Background = new SolidColorBrush(CurrentColor);
        }

Conclusion

The most impressive part of the control is the slider which calculates shades of the selected color. I hope the control is useful to many out there who require an Office 2007 style color picker. Please vote for the article if you find it interesting.

History

  • 17th January, 2010: Initial post

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