Introduction
This is a simple ComboBox
that displays images to the user. I saw many other solutions, most of which are complex and override most ComboBox
class properties and the draw methods which may cause a lot of problems.
This is a very simple method to add images in the ComboBox
es.
Fig 1
How to Use?
Copy the ImagedComoBox.exe from the project path bin\Release to your project directory. In Visual Studio, open the Solution Explorer, right click the project name, and choose Add Reference. Click Browse button, locate the ImagedComoBox.exe and select it. To display the control in Toolbox, right click on the toolbox, click Add/Remove Items. From the Customize Toolbox window, select the ImagedComoBox.exe.
Drag the ImagedComboBox
from the Toolbox and drop it in your form as shown in Fig 2.
<shape id="_x0000_i1026" style="WIDTH: 623.25pt; HEIGHT: 375pt" type="#_x0000_t75" alt="Fig2.png">
Fig 2. Drag and drop the control
Using the Code
The constructor:
- Sets the
ComboBoxStyle
to DropDownList
. You can change it as you need. - Sets owner draw mode
- Subscribes the
DrawItem
event
public ImagedComboBox()
{
DropDownStyle = ComboBoxStyle.DropDownList;
DrawMode = DrawMode.OwnerDrawVariable;
DrawItem += ComboBoxDrawItemEvent;
}
In the ComboBoxDrawItemEvent
: I draw the item content and the image.
I'm drawing the item background within the bounds specified in the Overload:System.Windows.Forms.DrawItemEventArgs
.
e.DrawBackground();
I'm drawing the item image at the specified location and with the specified size.
e.Graphics.DrawImage(comboboxItem.Image, e.Bounds.X,
e.Bounds.Y, ItemHeight, ItemHeight);
Parameters
comboBox.image
: Item Image, given with the item.e.BoundsX
: The-coordinate of the upper-left corner of the item image to draw.e.Bounds.Y
: The y-coordinate of the upper-left corner of the item image to draw.ItemHeight
: Width of the item image to draw.ItemHeight
: Height of the item image to draw.
You can also scale the image to the rectangle if you want to just use the property.destRect
: System.Drawing.Rectangle
structure that specifies the location and size of the drawn image.
After that, I draw the item text string in the calculated rectangle with the specified System.Drawing.Brush
and System.Drawing.Font
objects.
e.Graphics.DrawString(Items[e.Index].Value.ToString(), Font, Brushes.Black,
new RectangleF(e.Bounds.X + ItemHeight, e.Bounds.Y, DropDownWidth, ItemHeight));
Parameters
Items[e.Index]
: Selected itemfont
: System.Drawing.Font
that defines the text format of the string
brush
: System.Drawing.Brush
that determines the color and texture of the drawn textlayoutRectangle
: System.Drawing.RectangleF
structure that specifies the location of the drawn
The size of the layoutRectangle
is:
x = ComboBox top left x.
x= ComboBox top left y.
Width = Iterate through all items in Combobox and get MaxWidth.
Height = item height.
private void ComboBoxDrawItemEvent(object sender, DrawItemEventArgs e)
{
if (e.Index != -1)
{
var comboboxItem = Items[e.Index];
e.Graphics.DrawImage(comboboxItem.Image,
e.Bounds.X, e.Bounds.Y, ItemHeight, ItemHeight);
e.Graphics.DrawString(Items[e.Index].Value.ToString(), Font,
Brushes.Black, new RectangleF(e.Bounds.X + ItemHeight, e.Bounds.Y,
DropDownWidth, temHeight));
}
e.DrawFocusRectangle();
}
The ComboBox_MeasureItem
method measures the item.ToString()
width, the width is important to fit the item text inside the draw rectangle.
How Does It Work?
- Sets the
MaxWidth
initialize value to ImagedCombobox.Width
- Iterates through all items in the
ImagedCombobox
to find the new max width - Checks the
item.ToString()
measured width greater than the maxWidth
g.MeasureString(item.ToString(), Font).width).Where(width=> width> maxWidth))
- If greater, sets the
ComboBoxItem.Width
to maxWidth
and adds the offset
maxWidth = width;
DropDownWidth = maxWidth + 20;
Parameters
item.ToString()
: String to measure (ComboBoxItem
)font
: System.Drawing.Font
that defines the text format of the string
width
: Maximum width
of the string
private void ComboBox1_MeasureItem(object sender, MeasureItemEventArgs e)
{
var g = CreateGraphics();
var maxWidth = 0;
foreach (var width in Items.ItemsBase.Cast<object>().Select(element =>
(int)g.MeasureString(element.ToString(), Font).Width).Where(width => width > maxWidth))
{
maxWidth = width;
}
DropDownWidth = maxWidth + 20;
}
Important Classes
ComboBoxItem
: This class represents an ImagedComboBox
item which may contain an image and value.ComboCollection
: Collections of ComboBoxItem
History
- 1st September, 2010: Initial post