Public Class ImageComboBox Inherits ComboBox 'internal members for added properties Private _imageList As ImageList Private _imageindexmember As String 'imagelist to get the images from Public Property ImageList() As ImageList Get Return _imageList End Get Set(ByVal value As ImageList) _imageList = value End Set End Property 'property of the item object that holds the imageindex Public Property ImageIndexMember() As String Get Return _imageindexmember End Get Set(ByVal value As String) _imageindexmember = value End Set End Property Protected Overrides Sub OnDrawItem(ByVal ea As DrawItemEventArgs) 'this replaces the normal drawing of the dropdown list ea.DrawBackground() ea.DrawFocusRectangle() Dim imageSize As Size = ImageList.ImageSize Dim bounds As Rectangle = ea.Bounds Try Dim imageindex As Integer Dim display As String If Items(ea.Index).GetType Is GetType(Data.DataRowView) Then 'handle if datarow Dim d As Data.DataRowView = CType(Items(ea.Index), Data.DataRowView) imageindex = CType(d.Item(Me.ImageIndexMember), Integer) display = CType(d.Item(Me.DisplayMember), String) Else 'get the imageindex member from the item object imageindex = Items(ea.Index).GetType.GetProperty(Me.ImageIndexMember).GetValue(Items(ea.Index), Nothing) 'get the display member from the item object display = Items(ea.Index).GetType.GetProperty(Me.DisplayMember).GetValue(Items(ea.Index), Nothing) End If If imageindex <> -1 Then 'if the imageindex is set then draw the image ImageList.Draw(ea.Graphics, bounds.Left, bounds.Top, imageindex) ea.Graphics.DrawString(display, ea.Font, New SolidBrush(ea.ForeColor), bounds.Left + imageSize.Width, bounds.Top) Else 'no image just do the text ea.Graphics.DrawString(display, ea.Font, New SolidBrush(ea.ForeColor), bounds.Left, bounds.Top) End If Catch e As Exception 'handle things like the normal combo and don't use the display or imageindex member properties If ea.Index <> -1 Then ea.Graphics.DrawString(Items(ea.Index).ToString(), ea.Font, New SolidBrush(ea.ForeColor), bounds.Left, bounds.Top) Else ea.Graphics.DrawString(Me.Text, ea.Font, New SolidBrush(ea.ForeColor), bounds.Left, bounds.Top) End If Finally MyBase.OnDrawItem(ea) End Try End Sub Public Sub New() 'set to ownerdraw Me.DrawMode = DrawMode.OwnerDrawFixed End Sub Public Sub New(ByRef cbo As ComboBox) 'assign all properties from cbo to me 'Dim pi As Reflection.PropertyInfo 'For Each pi In cbo.GetType.GetProperties ' Dim s As String = pi.Attributes.ToString ' If pi.CanWrite Then ' 'On Error Resume Next 'just in case ' Me.GetType.GetProperty(pi.Name).SetValue(Me, pi.GetValue(cbo, Nothing), Nothing) ' End If 'Next 'TODO: have it consume ALL properties of original combo Me.Anchor = cbo.Anchor Me.BackColor = cbo.BackColor Me.BackgroundImage = cbo.BackgroundImage Me.CausesValidation = cbo.CausesValidation Me.ContextMenu = cbo.ContextMenu Me.DataSource = cbo.DataSource Me.DisplayMember = cbo.DisplayMember Me.Dock = cbo.Dock Me.DropDownStyle = cbo.DropDownStyle Me.DropDownWidth = cbo.DropDownWidth Me.Enabled = cbo.Enabled Me.Font = cbo.Font Me.ForeColor = cbo.ForeColor Me.IntegralHeight = cbo.IntegralHeight If cbo.Items.Count > 0 Then Dim tmp(cbo.Items.Count) As Object cbo.Items.CopyTo(tmp, 0) Me.Items.AddRange(tmp) End If Me.MaxDropDownItems = cbo.MaxDropDownItems Me.MaxLength = cbo.MaxLength Me.Sorted = cbo.Sorted Me.Text = cbo.Text Me.TabStop = cbo.TabStop Me.ValueMember = cbo.ValueMember Me.Visible = cbo.Visible Me.Location = cbo.Location Me.Size = cbo.Size Me.TabIndex = cbo.TabIndex 'set to ownerdraw Me.DrawMode = DrawMode.OwnerDrawFixed 'switch combos Dim parent As Object = cbo.Parent parent.Controls.Remove(cbo) parent.Controls.Add(Me) End Sub End Class 'just a sample class to use for items in this example Public Class ImgGenericList Private _Display As String Private _ID As Integer Private _Index As Integer = -1 Public Property Display() As String Get Return _Display End Get Set(ByVal Value As String) _Display = Value End Set End Property Public Property ID() As Integer Get Return _ID End Get Set(ByVal Value As Integer) _ID = Value End Set End Property Public Property Index() As Integer Get Return _Index End Get Set(ByVal Value As Integer) _Index = Value End Set End Property Public Sub New() MyBase.new() End Sub Public Sub New(ByVal display As String, ByVal id As Integer) Me.Display = display Me.ID = id End Sub Public Sub New(ByVal display As String, ByVal id As Integer, ByVal index As Integer) Me.Display = display Me.ID = id Me.Index = index End Sub End Class