Written in VS2008
This is my first control, so be gentle. It was created for a customer I'm writing an IT Work Order program for who wanted to show an image beside the Priority and Sub-Priority items.
The idea is based on NickThissen's ColorListBox control.
Here is a very simple owner-drawn ComboBox control that allows you to specify some Text (as normal) and an Image for each item. You can also align the Image to the Left or Right side of each item with the ImageAlign property.
How it works:
Akin to NickThissen's ColorListBox, the ImageComboBox class inherits ComboBox, and overloads the Items property. Instead of returning MyBase.Items, it returns its own ImageComboBoxItemCollection.
The original base items are then returned by a (private) property baseItems.
VBnet Code:
''' <summary> ''' Returns the items in the ImageComboBoxItemCollection to be used in the ImageComboBox. ''' </summary> <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _ Public Overloads ReadOnly Property Items() As ImageComboBoxItemCollection Get Return _Items End Get End Property ''' <summary> ''' The original items from the ImageComboBox that will never been seen. ''' </summary> Private ReadOnly Property baseItems() As ObjectCollection Get Return MyBase.Items End Get End Property
The ImageComboBoxItemCollection inherits System.Collections.ObjectModel.Collection(Of ImageComboBoxItem) and overrides the Set/Remove/InsertItem and ClearItems methods. In those methods, it adds the item to it's collection but also adds the item to the baseItems property of the owner ImageComboBox. This is necessary because the ImageComboBox won't draw any items in your own custom collection; only those in the MyBase.Items collection.
VBnet Code:
''' <summary> ''' Clears all the ImageComboBoxItems from both the ImageComboBoxCollection and the baseItems list of the ImageComboBox. ''' </summary> ''' <remarks></remarks> Protected Overrides Sub ClearItems() MyBase.ClearItems() _comboBox.baseItems.Clear() End Sub ''' <summary> ''' Inserts an ImageComboBoxItem at the specified index into the ImageComboBoxCollection and the baseItems list of the ImageComboBox. ''' </summary> ''' <param name="index">Index at which to insert the ImageComboBoxItem.</param> ''' <param name="item">The ImageComboBoxItem to be inserted.</param> ''' <remarks></remarks> Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As ImageComboBoxItem) MyBase.InsertItem(index, item) _comboBox.baseItems.Insert(index, item) End Sub ''' <summary> ''' Removes an ImageComboBoxItem at the specified index from the ImageComboBoxCollection and the baseItems list of the ImageComboBox. ''' </summary> ''' <param name="index">Index of the ImageComboBoxItem to be removed.</param> ''' <remarks></remarks> Protected Overrides Sub RemoveItem(ByVal index As Integer) MyBase.RemoveItem(index) _comboBox.baseItems.RemoveAt(index) End Sub ''' <summary> ''' Replaces an ImageComboBoxItem at the specified index with another ImageComboBoxItem in the ImageComboBoxCollection and the baseItems list of the ImageComboBox. ''' </summary> ''' <param name="index"></param> ''' <param name="item"></param> ''' <remarks></remarks> Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As ImageComboBoxItem) MyBase.SetItem(index, item) _comboBox.baseItems(index) = item End Sub
Finally, the ImageComboBox is owner drawn, so it overrides the OnDrawItem method. The combobox actually wants to draw the original items, but I simply force it to use the items from my own collection (by using their index), and draw them with the correct text and with an image.
Even with all this, you can pick and choose which items display an Image by leaving the ComboListBoxItem's Image property blank.
Enjoy!
