Introduction
I was searching the Internet for a WPF based color palette control to be used in my application. Since I didn't find one, I created one myself. The objective was to create a user control with WPF from which a user can get a (selected) color from the palette on the following events:
Now let’s see how the control is implemented.
Creating the Control
The color palette is essentially a WrapPanel which is composed of numerous Rectangle(s). (Note that words denoted in bold are WPF controls). All the Rectangle(s) are colored differently to give an effect of a color palette.
The user control is denoted by the name ColorPalette
which comprises numerous ColorPaletteItem
user controls. A ColorPaletteItem
is a user control itself, which consists of only one Rectangle. The ColorPaletteItem
control exposes three properties namely Red
, Blue
, and Green
. Each property is of type Byte
. These three basic colors go to make up any color, hence the need for these properties. When a ColorPaletteItem
control is loaded, the Rectangle is painted with the values from the three properties Red
, Blue
and Green
. It is shown in the code below:
Private Sub ColorPalette_Loaded(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs)
Handles MyBase.Loaded
Dim cpi As ColorPaletteItem
WrapPanel1.Width = m_width
Border1.Width = m_width
WrapPanel1.Height = m_height
Border1.Height = IIf((
216 Mod (Convert.ToInt32(m_width) / Convert.ToInt32(m_cellWidth))) = 0,
(216 * m_cellHeight / (Convert.ToInt32(m_width) / Convert.ToInt32(m_cellWidth))),
(216 * m_cellHeight / (Convert.ToInt32(m_width) / Convert.ToInt32(m_cellWidth))) +
m_height)
For i As Integer = 1 To 255 Step 50
For j As Integer = 1 To 255 Step 50
For k As Integer = 1 To 255 Step 50
cpi = New ColorPaletteItem
cpi.CellHeight = m_cellHeight
cpi.CellWidth = m_cellWidth
cpi.Red = Convert.ToByte(i)
cpi.Green = Convert.ToByte(j)
cpi.Blue = Convert.ToByte(k)
WrapPanel1.Children.Add(cpi)
Next
Next
Next
End Sub
The R, G, B values in the above code vary as 50 step variants. Also the height and width of the ColorPaletteItem
control can be set through CellHeight
, CellWidth
properties. The ColorPalette
control raises two events, namely:
ColorPaletteMouseMove
– This event is raised when the mouse is hovered over the palette.
ColorPaletteSelect
– This event is raised when a color is selected from the palette.
The events raised are shown in the code below:
Private Sub WrapPanel1_MouseLeftButtonDown(ByVal sender As System.Object, _
ByVal e As MouseButtonEventArgs)
Dim cpi As ColorPaletteItem
cpi = CType(e.Source, ColorPaletteItem)
Dim scb As SolidColorBrush
scb = CType(cpi.Rect.Fill, SolidColorBrush)
m_SelectedColor = scb.Color
RaiseEvent ColorPaletteSelect(Me, m_SelectedColor)
End Sub
Private Sub WrapPanel1_MouseMove(ByVal sender As System.Object, _
ByVal e As System.Windows.Input.MouseEventArgs)
Dim cpi As ColorPaletteItem
cpi = CType(e.Source, ColorPaletteItem)
Dim scb As SolidColorBrush
scb = CType(cpi.Rect.Fill, SolidColorBrush)
m_CurrentColor = scb.Color
RaiseEvent ColorPaletteMouseMove(Me, m_CurrentColor)
End Sub
Both the above events pass the Color object to the event handlers. This Color object represents the color on which the mouse hovers or the mouse select happens.
Using the Control
Now let’s create a WPF Windows application which uses the above color palette control. Create a new project WPFColorpaletteHost
. Right click on the project and add a reference to the project which contains the color palette control. Now add a new file Window1.xaml. Edit the file to include the namespace
in the root element (Window
) as follows:
xmlns:my="clr-namespace:Colorpalettecontrol;assembly=ColorPaletteControl"
Now declare the colorpalette
control in the XAML file as follows:
<my:ColorPalette Name="ColorPalette1" PaletteHeight="300" PaletteWidth="720"
CellHeight="20" CellWidth="20" ColorPaletteMouseMove="ColorPalette_ColorPaletteMouseMove"
ColorPaletteSelect="ColorPalette_ColorPaletteSelect"
Margin="11,0,0,0" HorizontalAlignment="Left"
Width="767" Height="310" VerticalAlignment="Top"> </my:ColorPalette>
Define two functions in Window1.xaml.vb to handle the Colorpalette
events as follows:
Private Sub ColorPalette_ColorPaletteMouseMove(ByVal sender As System.Object,
ByVal c As
System.Windows.Media.Color)
Dim scb As SolidColorBrush
If (c = Nothing) Then
Canvas1.Background = Brushes.DarkGray
scb = CType(Canvas1.Background, SolidColorBrush)
SetValues(scb.Color.R.ToString(), scb.Color.G.ToString(),
scb.Color.B.ToString())
Else
scb = New SolidColorBrush
scb.Color = c
Canvas1.Background = scb
SetValues(c.R, c.G, c.B)
End If
End Sub
Private Sub ColorPalette_ColorPaletteSelect(ByVal sender As System.Object,
ByVal c As
System.Windows.Media.Color)
Dim scb As SolidColorBrush
scb = New SolidColorBrush
scb.Color = c
Canvas1.Background = scb
SetValues(c.R, c.G, c.B)
End Sub
We can also define a canvas which displays the color as the mouse hovers over the palette. The three text boxes each display Red
, Green
, Blue
components of the hovered/selected color.
I've also used the control from a Windows Forms application. (Refer to the attached sample solution).
Conclusion
This colorpalette
control can be highly customized to have custom color ranges instead of predefined ranges. We can have a collection property through which we can give a list of colors to be populated in the palette. This gives the flexibility of getting more/less range of colors than already present. I would post that implementation shortly.
History
- 19th February, 2008: Initial post