Creating custom colorpicker in Silverlight
During the creation of a smaller application I found myself in need of a custom color picker, I wanted something in the same style as can be found in the ComponentOne toolkit. To accomplish this I created a class extending the System.Windows.Controls.Button class, the file called ColorPicker.cs is shown below:
public class ColorPicker : Button
{
private Popup popup;
public ColorPicker()
{
popup = new Popup();
Style = Application.Current.Resources["ColorPicker"] as Style;
Click += new RoutedEventHandler(ColorPicker_Click);
}
void ColorPicker_Click(object sender,RoutedEventArgs e)
{
if(popup.IsOpen)
{
popup.IsOpen = false;
}
else
{
ColorPickerControl cpc = new ColorPickerControl();
cpc.SetProperties(this, popup);
popup.Child = cpc;
FrameworkElement page = Application.Current.RootVisual as FrameworkElement;
GeneralTransform gt = ((Button)sender).TransformToVisual(page);
Point point = gt.Transform(new Point(0,((Button)sender).ActualHeight));
popup.VerticalOffset = point.Y;
popup.HorizontalOffset = point.X;
((ColorPickerControl)popup.Child).Width = 175;
((ColorPickerControl)popup.Child).Height = 200;
popup.IsOpen = true;
}
}
}
| In the example above I use a custom style to get the desired look of my color picker, below is the style which I am using in the example, this style yields the result you can see to the right. The blue area of course changes depending on which color you select: |
<Style x:Key="ColorPicker" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.1" To="MouseOver"/>
<VisualTransition From="Normal" GeneratedDuration="00:00:00.3000000" To="MouseOver"/>
<VisualTransition From="MouseOver" GeneratedDuration="00:00:00.5000000" To="Normal"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="HoverBorder" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="0" Value="0.6"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2,2,2,2">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Width="{TemplateBinding Width}">
<Border Width="{TemplateBinding Width}" x:Name="BackgroundGradient" BorderThickness="1" Background="{TemplateBinding Background}"/>
<Border Margin="-20,0,0,0" Width="20" Background="Wheat">
<Path Height="4" HorizontalAlignment="Right" Margin="4,0,6,0" Width="8" Stretch="Uniform" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z ">
<Path.Fill>
<SolidColorBrush Color="#FFFFFFFF"/>
</Path.Fill>
</Path>
</Border>
</StackPanel>
</Border>
<Border x:Name="HoverBorder" Opacity="0" BorderBrush="{StaticResource NormalBrush}" BorderThickness="2,2,2,2" CornerRadius="2,2,2,2"/>
<Border x:Name="DisabledVisualElement" IsHitTestVisible="False" Opacity="0" Background="#FFFFFFFF" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2,2,2,2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Black" />
</Style>
To show the actual color picker I created a custom control and named it ColorPickerControl. I will hurry up and say that it was made as fast as possible just to serve as an example, so what is seen is just a simple 5 by 6 grid with some restyled buttons. In a real life application it would be prudent to create a prettier color picker control, and possible one with more features like for example the one in Microsoft Word.
Custom Colorpicker Control
Below is shown some parts of the CustomColorPicker.xaml file, the main things being the custom button style, as well as an example button making use of this style.
<Style x:Key="ColorOptionButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#FF1F3B53"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions/>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Rectangle x:Name="BackgroundGradient" Fill="{TemplateBinding Background}" Margin="1"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button x:Name="ColorWhite" Background="White" Grid.Row="0" Grid.Column="0" Style="{StaticResource ColorOptionButtonStyle}"></Button>
Finally you can add the control as you would any other, and depending on your implementation of the CustomColorPicker.cs code behind file you can get the selected color.
<Controls:ColorPicker x:Name="ColorButton" Width="120" HorizontalAlignment="Left" Height="24" Grid.Column="1" Grid.Row="4"/>
If you have any questions or suggestions please feel free to post a comment.
/Peter
Edit: As requested I have added a live example… Please remember it falls to yourself to style it
|
|








September 8th, 2010 at 04:33
Nice
September 8th, 2010 at 04:54
Hi, do you have a live example of this so we can see it in action? Thanks for sharing…
http://www.pokerdiy.com/poker-blinds-timer.aspx
September 8th, 2010 at 09:03
Hello rod,
I have added a live example so you could have a look at the colorpicker in action…
Best regards
/Peter
November 5th, 2010 at 00:19
Solid post – and great domain by the way!
November 13th, 2010 at 21:46
Uncanny, thanks for posting!
December 17th, 2010 at 17:09
great post, thanks for sharing
May 12th, 2011 at 22:45
Can you post the code?
May 23rd, 2011 at 10:17
Hi vijay
Im afraid i have deleted the project, it should not be a problem to reproduce it from the code posted. It is not that pretty though, and I have since optimized a bit on it – since I have found some issues with using this in collaboration with the NavigationFramework. I might post a better solution for this at some later time
But for the question, I will leave you to reconstruct the code from the example – should there however be any problems you are welcome to mail me your reconstruction and I will have a look at it…
Best Regards
/Peter