|
|
Title |
A Simple Colour Picking ComboBox using OwnerDraw and Reflection.
|
Summary |
This simple tutorial demonstrates the using an Owner Draw ComboBox to allow the user to select from a prefined set of colours. The colours are gathered by enumerating the Color and KnowColor objects. |
Contributor |
John McTainsh
|
Published |
1-Apr-2002 |
Last updated |
1-Apr-2002 |
|
|
Download Demo - 2 Kb
Download Full Source - 18 Kb
Download Demo.exe - 4 Kb
Introduction
Here is a simple drop down ComboBox that allows the operator to select a
colour from a predefined set of colours. The code also demonstrates a simple
implementation of an Owner draw control and using Reflection to enumerate the
available colours. We will cover how to use the control and then for who ever is
interested, we will cover how the control works.
How to Install and Use
- Open the Project and Solution Explorer.
- Right click on the Project in the solution Explorer
- Choose the "Add"->"Add Existing Item.." menu.
- Browse to the ComboBoxColors.cs file and select it.
- It should appear in the Solution exploder as a Component. There must be a
better way to do the following. ( Please email to ComboBoxColors@mctainsh.com
)
- Place a ComboBox on your form.
- Close the form and open then source file.
- Add
#using AntarcticSolutions; to the top of the file.
- Replace all instances of
System.Windows.Forms.ComboBox with ComboBoxColors .
(Be sure to Expand the Windows Form Designer generated code region
first)
- In the
FormLoad or constructor after the Combobox has been
created call LoadBaseColors() or LoadAllWindowsColors()
set the colours up in the ComboBox.
- At this time you could also set the initial colour with
m_comboBoxColors.LoadAllWindowsColors();
m_comboBoxColors.SelectedColor = Color.Red;
Note: LoadAllWindowsColors() will load all the standard named
colours and also load the known Windows colours such as "Menu" and "ScrollBar".
If you do not want these colours then call LoadBaseColors() .
OwnerDraw
Each item in the ComboBox contains the items colour name as text and a box
next to it showing a sample of the colour. To achieve this we use perform the
drawing of the control ourselves by setting the controls DrawMode to
OwnerDrawFixed and
by providing our own implementation of OnDrawItem(...) . In the constructor we call the following
to set the style and point to our own Drawing method;
DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
DrawItem += new System.Windows.Forms.DrawItemEventHandler( OnDrawItem );
In the following code we draw the colour sample and text string of the colour
we are drawing. This method is called for each item that is draw in the list and
for the selected item next to the drop down arrow. Note, we try to use as much
data as we can from the passed in DrawItemEventArgs . This ensures
if the used uses there own background colour or font size, the Colour Combobox
will still like all the other standard window controls.
private void OnDrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
// Fill in the background
e.Graphics.FillRectangle( new SolidBrush( e.BackColor ), e.Bounds );
if( e.Index < 0 )
return;
// Work out where every thing goes
int nX = e.Bounds.Left;
int nY = e.Bounds.Top;
int nMarg = 2;
int nH = e.Bounds.Height-(2*nMarg);
string sText = Items[e.Index].ToString();
// Draw the Colour Gymph
Pen penFore = new Pen( e.ForeColor );
Rectangle rectGymph = new Rectangle( nX+nMarg, nY+nMarg, nH, nH );
e.Graphics.FillRectangle( new SolidBrush( Color.FromName( sText ) ), rectGymph );
e.Graphics.DrawRectangle( penFore, rectGymph );
// Draw the text
e.Graphics.DrawString(
sText, e.Font, new SolidBrush( e.ForeColor ),
nX + nH + (2*nMarg), e.Bounds.Top );
}
Get the List of Available Colours
The Color structure contains a list of predefined colours in the
form of public static properties and the KnownColor enumerator
defines a set of named and system colours. Each is used as follows;
Color clrRaceCar = Color.Red;
Color clrFrame = Color.FromKnownColor( KnownColor.ActiveBorder );
To populate the ComboBox with these colours we need a list of them. To do
this we use reflection to add the items to the Combobox Items
collection as follows;
using System.Drawing;
using System.Reflection;
...
public void LoadBaseColors()
{
Items.Clear();
PropertyInfo [] aryPI = typeof( Color ).GetProperties(
BindingFlags.Public | BindingFlags.Static );
foreach( PropertyInfo pi in aryPI )
Items.Add( pi.Name );
}
public void LoadAllWindowsColors()
{
Items.Clear();
FieldInfo [] aryPI = typeof( KnownColor ).GetFields(
BindingFlags.Public | BindingFlags.Static );
foreach( FieldInfo pi in aryPI )
Items.Add( pi.Name );
}
Note: for the enumerator we use FieldInfo and for the
structure we use the PropertyInfo class;
Conclusion
With a relatively small amount of code we have been able to enumerate
all the colours and draw then in a ComboBox. This method class could also be
altered to show graphic line types or line widths for user selection.
|