How to Display Images in ComboBox in 5 Minutes?






4.86/5 (19 votes)
This is an extended ComboBox which supports images for items
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.
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.
Using the Code
The constructor:
- Sets the
ComboBoxStyle
toDropDownList
. You can change it as you need. - Sets owner draw mode
- Subscribes the
DrawItem
event
public ImagedComboBox()
{
//Specifies that the list is displayed by clicking the down arrow
//and that the text portion is not editable.
//This means that the user cannot enter a new value.
//Only values already in the list can be selected. The list displays only if
DropDownStyle = ComboBoxStyle.DropDownList;
//All the elements in the control are drawn manually and can differ in size.
DrawMode = DrawMode.OwnerDrawVariable;
//using DrawItem event we need to draw item
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.
//we need to draw the item as string because we made drawmode to ownervariable
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 thestring
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.
/// </summary>
/// Draws overridden items.
/// <param name="sender"></param>
/// <param name="e"></param>
private void ComboBoxDrawItemEvent(object sender, DrawItemEventArgs e)
{
//Draw background of the item e.DrawBackground();
if (e.Index != -1)
{
// selected item
var comboboxItem = Items[e.Index];
//Draw the image in combo box using its bound and ItemHeight
e.Graphics.DrawImage(comboboxItem.Image,
e.Bounds.X, e.Bounds.Y, ItemHeight, ItemHeight);
//we need to draw the item as string because we made drawmode to ownervariable
e.Graphics.DrawString(Items[e.Index].Value.ToString(), Font,
Brushes.Black, new RectangleF(e.Bounds.X + ItemHeight, e.Bounds.Y,
DropDownWidth, temHeight));
}
//draw rectangle over the item selected
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 toImagedCombobox.Width
- Iterates through all items in the
ImagedCombobox
to find the new max width - Checks the
item.ToString()
measured width greater than themaxWidth
g.MeasureString(item.ToString(), Font).width).Where(width=> width> maxWidth))
- If greater, sets the
ComboBoxItem.Width
tomaxWidth
and adds the offsetmaxWidth = width; DropDownWidth = maxWidth + 20;
Parameters
item.ToString()
: String to measure (ComboBoxItem
)font
:System.Drawing.Font
that defines the text format of thestring
width
: Maximumwidth
of thestring
/// <summary>
/// I have set the Draw property to DrawMode.OwnerDrawVariable,
/// so I must calculate the item measurement.
/// I will set the height and width of each item before it is drawn.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 anImagedComboBox
item which may contain an image and value.ComboCollection
: Collections ofComboBoxItem
History
- 1st September, 2010: Initial post