Click here to Skip to main content
15,867,488 members
Articles / Desktop Programming / WPF

WPF ColorPicker and BrushEditor

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
25 Jun 2012CPOL2 min read 31K   1.3K   18   8
Similar to KAXAML's.

Introduction 

Well, I still hadn't found the perfect WPF ColorPicker Control to use in my projects. There are some nice ones out there, but my favourite is KAXAML's, so, I thought I might try to replicate it.  

Background  

The project is loosely MVVM and contains two UserControls, ColorEditor and BrushEditor<code> <code>and are packaged in a separate class library project for your convenience.  

The first hurdle I had was trying to generate the ColorPicker swatch. WriteableBitmap was terribly slow, so I decided to cache the 100 Hue swatches (being 0 - 1 with increments of 1%). Generating the Bitmaps was made much easier (having never had an occasion to use them) with the SimpleBitmap class found in the Community Content section of WriteableBitmap (http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx)  

The next hurdle for me was retemplating the Sliders for Hue and Alpha, again, something I hadn't done before. I mucked about with a couple of ControlTemplates before taking KAXAML's own Simple Styles style and bending it to my will. The Hue Slider background is simply a Border with a LinearGradientBrush and 7 GradientStops.  

The Alpha Slider and selected color box were somewhat tricky too, and I must profess to not fully understanding why the DrawingBrush that displays the checker pattern works.  

However, I think the trickiest part of this, to my surprise, was actually the RGBA/HSLA TextBox's! Basically, the problem is this. If you update say, the R value, you must also update H, S and L. If you update H, you must update R, if you update S, you must update R. This mightn't be so bad except that the conversion code from RGB to HSL isn't perfect. Ie, HSL (0.56, .60, .23) might not align perfectly to an RGB value.  So, it rounds the RGB value. But perhaps that rounding alters the H value just a tiny bit. So we alter the RGB values, which skew the H just a tiny bit. In the end, I simply said, if you change the H value, set a flag, update the RGB values, when they attempt to update the HSL values, check if that flag is set. If so, don't update. Simple in retrospect of course. 

Using the code   

The editors are used just like any other UserControl.

XML
<Window 
    x:Class="BrushEditor.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ColorEditor="clr-namespace:Lovatts.ColorEditor;assembly=Lovatts.ColorEditor" 
    Title="MainWindow" 
    Height="350" 
    Width="525">

  <ColorEditor:BrushEditor></ColorEditor:BrushEditor>
</Window>

But you can also bind to/use the underlying ViewModels: 

C#
ColorEditor colorEditor = new ColorEditor();
colorEditor.ColorEditorViewModel.Color = Colors.Blue;
colorEditor.ColorEditorViewModel.RGB.A = 67;
C#
Lovatts.ColorEditor.BrushEditor brushEditor = new Lovatts.ColorEditor.BrushEditor();
brushEditor.BrushEditorViewModel.BrushType = BrushTypes.Radial;
brushEditor.BrushEditorViewModel.Center = new Point(1, 0);
brushEditor.BrushEditorViewModel.GradientStops.Clear();   
brushEditor.BrushEditorViewModel.GradientStops.Add(new GradientStopViewModel(Colors.Blue, 1);  
brushEditor.BrushEditorViewModel.GradientStops.Add(new GradientStopViewModel(Colors.Red, 0));

Brush serialization/deserialization methods are included for convenience. 

C#
string xml = brushEditor.BrushEditorViewModel.SerializeBrushToXml();
brushEditor.BrushEditorViewModel.DeserializeBrushFromXml(xml);

The XML output being...

XML
<RadialGradientBrush
  Center="1,0" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <RadialGradientBrush.GradientStops>   
    <GradientStop
      Color="#FFFF0000"
      Offset="0" />
    <GradientStop
      Color="#FF0000FF"
      Offset="1" />
  </RadialGradientBrush.GradientStops>
</RadialGradientBrush>

Points of Interest

Well.. this is my first ever CodeProject submission and took about a day to write. 

There's a slight issue when changing the hue slider, in that it will sometimes snap the palette thumb to an RGB value.  

The hex code TextBox is automatically set to OverType (using the method below) which I find much more user friendly:  

C#
private void MakeHexTextBoxOverType()
{
    PropertyInfo textEditorProperty = typeof (TextBox).GetProperty(
       "TextEditor", BindingFlags.NonPublic | BindingFlags.Instance);
    object textEditor = textEditorProperty.GetValue(hexTextBox, null);
    // set _OvertypeMode on the TextEditor
    PropertyInfo overtypeModeProperty = textEditor.GetType().GetProperty(
       "_OvertypeMode", BindingFlags.NonPublic | BindingFlags.Instance);
    overtypeModeProperty.SetValue(textEditor, true, null);
} 

History 

  • 19/6/2012: Posted article.
  • 20/6/2012: Uploaded source 
  • 26/6/2012: Updated Background 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Lovatts Publications
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Amin Esmaeily14-Aug-13 0:35
professionalAmin Esmaeily14-Aug-13 0:35 
GeneralMy vote of 5 Pin
Jaikrishan11-Mar-13 0:13
Jaikrishan11-Mar-13 0:13 
GeneralRe: My vote of 5 Pin
Matthew Searles14-Apr-13 19:13
Matthew Searles14-Apr-13 19:13 
QuestionSuggestion : Add some screenshot Pin
AmitGajjar19-Jun-12 20:29
professionalAmitGajjar19-Jun-12 20:29 
AnswerRe: Suggestion : Add some screenshot Pin
Matthew Searles20-Jun-12 14:02
Matthew Searles20-Jun-12 14:02 
GeneralRe: Suggestion : Add some screenshot Pin
Matthew Searles20-Jun-12 14:16
Matthew Searles20-Jun-12 14:16 
QuestionNice pickers there Pin
Sacha Barber19-Jun-12 1:55
Sacha Barber19-Jun-12 1:55 
I like these

Though you need to post the source code
Sacha Barber
  • Microsoft Visual C# MVP 2008-2012
  • Codeproject MVP 2008-2012
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Nice pickers there Pin
Matthew Searles19-Jun-12 20:17
Matthew Searles19-Jun-12 20:17 

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

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