Click here to Skip to main content
11,704,107 members (64,468 online)
Click here to Skip to main content

WPF ColorPicker and BrushEditor

, 25 Jun 2012 CPOL 14.4K 915 19
Rate this:
Please Sign up or sign in to vote.
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 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.

<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: 

ColorEditor colorEditor = new ColorEditor();
colorEditor.ColorEditorViewModel.Color = Colors.Blue;
colorEditor.ColorEditorViewModel.RGB.A = 67;
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. 

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

The XML output being...

<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:  

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)

Share

About the Author

Matthew Searles
Software Developer Lovatts Publications
Australia Australia
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 5 Pin
S.A.Esmaeily14-Aug-13 0:35
memberS.A.Esmaeily14-Aug-13 0:35 
GeneralMy vote of 5 Pin
Jaikrishan11-Mar-13 0:13
memberJaikrishan11-Mar-13 0:13 
GeneralRe: My vote of 5 Pin
Matthew Searles14-Apr-13 19:13
memberMatthew Searles14-Apr-13 19:13 
QuestionSuggestion : Add some screenshot Pin
amitgajjar19-Jun-12 20:29
memberamitgajjar19-Jun-12 20:29 
AnswerRe: Suggestion : Add some screenshot Pin
Matthew Searles20-Jun-12 14:02
memberMatthew Searles20-Jun-12 14:02 
GeneralRe: Suggestion : Add some screenshot Pin
Matthew Searles20-Jun-12 14:16
memberMatthew Searles20-Jun-12 14:16 
QuestionNice pickers there Pin
Sacha Barber19-Jun-12 1:55
mvpSacha Barber19-Jun-12 1:55 
GeneralRe: Nice pickers there Pin
Matthew Searles19-Jun-12 20:17
memberMatthew Searles19-Jun-12 20:17 

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 | Terms of Use | Mobile
Web02 | 2.8.150819.1 | Last Updated 26 Jun 2012
Article Copyright 2012 by Matthew Searles
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid