65.9K
CodeProject is changing. Read more.
Home

Silverlight ColorPicker

starIconstarIconstarIconstarIconstarIcon

5.00/5 (18 votes)

Jan 8, 2011

CPOL

2 min read

viewsIcon

254798

downloadIcon

3842

A Silverlight color picker (looks like ComboBox), more like the one used within VS 2010 property browser for editing color-type

SilverlightColorPicker1.png

SilverlightColorPicker2.png

Introduction

Last year, I was engaged in an ASP.NET Ajax project. We needed to build a very complex Silverlight control. My job was to build this Silverlight control. Silverlight is amazing. But a lot of common controls such as ToolBar, ContextMenu, etc. are not there. You need to buy or create. In this article, I'd like to talk about a color-picker control with drop-down color selection capabilities, more like the one used within Visual Studio 2010 property browser for editing color-typed.

We Need a ColorPicker has that Feeling

One day, we needed a ColorPicker control in our Silverlight project. I found a lot of them, open source and needed to purchase one. None of them was perfect nor had the feeling we wanted. We wanted a color picker like ComboBox or DatePicker. We wanted a color picker that a user can find predefined colors or customize their own ones. The requirement was abandoned finally.

I liked the feeling of the color picker used within VS 2010 property browser. So I created a color picker like it.

Using the ColorPicker

My color picker is very easy to use.

  • Color: The only one special property, get or set current selected color
  • ColorChanged: The only one special event, occurs when the Color property is changed

In the *.xaml file:

<UserControl x:Class="SilverlightControls.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mine="clr-namespace:SilverlightControls"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="600">

    <Grid x:Name="LayoutRoot" Background="White">
        <mine:ColorPicker Height="23" HorizontalAlignment="Left" 
	VerticalAlignment="Top" Margin="50,50" x:Name="colorPicker1" 
	Width="150" Color="Red" ColorChanged="colorPicker1_ColorChanged">
        </mine:ColorPicker>
    </Grid>
</UserControl>

In the *.cs file:

namespace SilverlightControls
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void colorPicker1_ColorChanged
	(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (colorPicker1 != null)
            {
                MessageBox.Show(colorPicker1.Color.ToString());
            }
        }
    }
}

About ColorPicker's Drop-down Part: ColorBoard

I named the drop-down part of my ColorPicker as ColorBoard. There are three parts in ColorBoard.

  • Part 1: The left-top part is the HSV part
  • Part 2: The right-top part is the ARGB part
    About the HSV color model, and the converting between with ARGB color model, you can reference a Wikipedia article. (http://en.wikipedia.org/wiki/HSL_and_HSV)
  • Part 3: The bottom part is the predefined colors part. That is a ComboBox. Current order is windows default order.
    If you want to use alphabet order, comment line 26 in PredefinedColor.cs and uncomment line 29 in the same file.
    In file PredefinedColor.cs.
    // "Aqua" and "Cyan" are same color 
    // (0xFF00FFFF). "Fuchsia" and "Magenta" are same color (0xFFFF00FF).
    
    line 23:    private static void Initialize()
    line 24:    {
    line 25:        // "Aqua" and "Fuchsia" will not be in Dictionary
    line 26:        Initialize_Windows();
    line 27:
    line 28:        // "Cyan" and "Magenta" will not be in Dictionary
    line 29:        //Initialize_Alphabet();
    line 30:    }

How to Draw S-V Rectangle?

This question is the most difficult to resolve. It troubled me for a long time. Set every-point's color? No, that is stupid.

Finally, I got the solution: use two LinearGradientBrushes. One horizontal direction is for saturation(S). And another vertical direction is for Value(V).

<Rectangle x:Name="RectangleRootHSV" Width="80"
Height="80" Stroke="{StaticResource BorderBrush}" StrokeThickness="1">
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
            <GradientStop Color="#FFFFFFFF" Offset="0" />
            <GradientStop x:Name="GradientStopHSVColor"
            Color="#FFFF0000" Offset="1" />
        </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

<Rectangle x:Name="RectangleHSV" Width="80" Height="80">
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="#00000000" Offset="0" />
            <GradientStop Color="#FF000000" Offset="1" />
        </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

History

  • Version 1.0 (2010-12-30) - Initial release