Click here to Skip to main content
15,885,366 members
Articles / Desktop Programming / Windows Forms

How to Display Images in ComboBox in 5 Minutes?

Rate me:
Please Sign up or sign in to vote.
4.86/5 (20 votes)
1 Sep 2010CPOL2 min read 139.9K   8.9K   43   19
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 ComboBoxes.

Fig1.png

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">

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
C#
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.

C#
e.DrawBackground();

I'm drawing the item image at the specified location and with the specified size.

C#
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.

C#
//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 item
  • font: System.Drawing.Font that defines the text format of the string
  • brush: System.Drawing.Brush that determines the color and texture of the drawn text
  • layoutRectangle: System.Drawing.RectangleF structure that specifies the location of the drawn

The size of the layoutRectangle is:

C#
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 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
    C#
    g.MeasureString(item.ToString(), Font).width).Where(width=> width> maxWidth))  
  • If greater, sets the ComboBoxItem.Width to maxWidth and adds the offset
    C#
    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
C#
/// <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 an ImagedComboBox item which may contain an image and value.
  • ComboCollection: Collections of ComboBoxItem

History

  • 1st September, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Agilent
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionrequest for video tutorial Pin
Member 1468761512-Dec-19 8:49
Member 1468761512-Dec-19 8:49 
AnswerRe: request for video tutorial Pin
OriginalGriff12-Dec-19 8:54
mveOriginalGriff12-Dec-19 8:54 
QuestionNew Bitmap calling ComboBoxDrawItemEvent Pin
Member 1295812726-Nov-19 5:37
Member 1295812726-Nov-19 5:37 
SuggestionDrawItem event Pin
oliwan11-Oct-16 7:51
oliwan11-Oct-16 7:51 
Questiondoesn't work on VS2012 Pin
Member 1238508411-Mar-16 0:56
Member 1238508411-Mar-16 0:56 
AnswerRe: doesn't work on VS2012 Pin
Member 1238508414-Mar-16 0:16
Member 1238508414-Mar-16 0:16 
Questionadd image from sql into combobox (with c#) Pin
Member 117825394-Oct-15 1:34
Member 117825394-Oct-15 1:34 
Questionproblem in design + items.clear Pin
Member 111235772-Oct-14 2:20
Member 111235772-Oct-14 2:20 
SuggestionAlert Pin
Cyprien Caron25-Apr-14 5:32
Cyprien Caron25-Apr-14 5:32 
GeneralRe: Alert Pin
Bassam Alugili30-Apr-14 1:46
Bassam Alugili30-Apr-14 1:46 
QuestionCentering the label Pin
Hanika20-Nov-13 8:31
Hanika20-Nov-13 8:31 
SuggestionDisplayMember Pin
Member 891572411-Mar-13 7:32
Member 891572411-Mar-13 7:32 
GeneralMy vote of 5 Pin
Member 89157247-Dec-12 5:18
Member 89157247-Dec-12 5:18 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 10:56
professionalKanasz Robert27-Sep-12 10:56 
GeneralHighlighted Text Pin
Kelvin L Miller26-Apr-11 5:10
Kelvin L Miller26-Apr-11 5:10 
General.NET 2.0 Solution Pin
Jtoland3-Nov-10 2:05
Jtoland3-Nov-10 2:05 
I'm trying to mimic something similar to this, however, unfortunately, I'm stuck working in C# with .NET 2.0 and so this, as shown, won't build. You don't happen to know how to genralize this to a .NET 2.0 solution, do you?
GeneralRe: .NET 2.0 Solution Pin
EtherealMonkey3-Feb-11 17:01
EtherealMonkey3-Feb-11 17:01 
GeneralMy vote of 4 Pin
AndySummer6-Sep-10 20:09
AndySummer6-Sep-10 20:09 
GeneralRe: My vote of 4 Pin
Member 444846018-Oct-10 20:29
Member 444846018-Oct-10 20:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.