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

Tagged as

Go to top

WPF Color Picker Like Office 2007

, 17 Jan 2010
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Saraf Talukder
Software Developer
United Kingdom United Kingdom
Currently living and working in London. He is an enthusiastic software developer passionate about microsoft technologies, specially C#, WPF, Silverlight WCF and windows Azure. Contributes to several open source project and msdn forums.
 
My Blog
twitter : @sarafuddin
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 5 Pinmemberkrisstoddart13-Oct-10 0:09 
GeneralRe: My vote of 5 PingroupSaraf Uddin Talukder16-Jan-11 3:04 

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
Web03 | 2.8.140926.1 | Last Updated 17 Jan 2010
Article Copyright 2010 by Saraf Talukder
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid