M  oving Target Software

Moving Target Software - What Happened to ItemData for ComboBoxes and ListBoxes?

Users of Visual Basic 6 would be well aware of the "ItemData" property of the ComboBox or ListBox control. This useful little array of strings allowed you to associate a piece of data with each item in your control and use this data when a user selected a particular item in the control.

Typically what I used it for was to store a unique key value. So for example, if I had a database with a table containing a list of countries, I could have a unique number describing each one and store this number in the ItemData property of a ComboBox or ListBox and the country name in the List of the control. Thus when a user selected a country getting the id for the country was trivial and storing it in a detailed database record was simple. In Visual Basic 6 Code to do this could look like:

If Form1.ComboBox1.ListIndex <> -1 Then
  intItemIndex = Form1.ComboBox1.ItemData(Form1.ComboBox1.ListIndex)
End If

OK, this was easy enough, in VB .NET this useful property has dissappeared. Fear not intrepid coder, in it's place is something much nicer, though not immediately obvious. In VB .NET the ComboBox and ListBox Windows Forms Controls have lists of Objects rather than simple text arrays. Objects, can of course, contain any sort of data you like, and this data is associated with individual list items. Lets look at adding an item to a ComboBox in VB .NET:

ComboBox1.Items.Add("ListItem1"

You have added the string object to the ComboBox list. What if you want to add something a little more complex? Lets define a class of our own and add this to the list!

Public Class clsComboBoxItem
  Private m_ItemText As String
  Private m_ItemIndex As Int32

  Public Sub New(ByVal strItemText As StringByVal intItemIndex As Int32)
    m_ItemText = strItemText
    m_ItemIndex = intItemIndex
  End Sub

  Public ReadOnly Property ItemIndex() As Int32
    Get
      Return m_ItemIndex
    End Get
  End Property

  Public ReadOnly Property ItemText() As String
    Get
      Return m_ItemText
    End Get
  End Property
End Class

Lets add an item of this class to the ComboBox

ComboBox1.Items.Add(New clsComboBoxItem("ItemText",15)) 

OK that looks great. No wait, what is the ComboBox going to display? We've given it two pieces of data so which one does it show? Well it will use the "ToString()" method of the class, remembering that any Object we create inherits some default properties from System.Object. We can set exactly what the ComboBox displays in two ways. The first uses inheritance to "Override" the "ToString()" method of the System.Object class. To do this our class definition will have the following extra method added to it's definition:

Public Overrides Function ToString() as String
  Return m_ItemText
End Function

The second way is via the property "DisplayMember" of the ComboBox that defines which property of the Objects in the ComboBox list will be displayed. You might like to use this way if you are overriding the ToString method for some other reason. Let's see what that might look like in our case:

ComboBox1.DisplayMember="ItemText"

Well now you have your data in your ComboBox or in your ListBox. Getting the selected text value from this is simple, just use the "Text" property of the control. How do you get the associated index data? Well there's a couple of ways, the first uses the property "ValueMember" or the ComboBox or ListBox. The works like this:


'
'Set the ValueMember of your control, this should be text equal to one
'the properties of your custom class you have filled the control with

ComboBox1.ValueMember="ItemIndex"



'To display the selected value of the control, you could place the
'the following code in the SelectIndexChanged event of a ComboBox
'or the SelectedValueChanged event of a ListBox

MsgBox "Selected Index is" & cstr(ComboBox1.SelectedValue)

The first way is fine if you just have one piece of associated data with each list or combo item, but you can of course associate as much data as you like with each item. Getting that data out done a little differently. The following code explains it pretty well:


'Dim a new ComboBox item

Dim itmCombo As clsComboBoxItem = New clsComboBoxItem(""0)

'Check that the selected item in your combo is of type clsComboBoxItem

If ComboBox1.SelectedItem.GetType.ToString = itmCombo.GetType.ToString Then

  'If the SelectedItem is of the correct type you can now store it in your class instance
  'using the Ctype function

  itmCombo = CType(ComboBox1.SelectedItemclsComboBoxItem)

  'The members of the class instance are now exposed for use

  MsgBox("Item Text=" & itmCombo.ItemText & " and ItemIndex=" & CStr(itmCombo.ItemIndex))
End If


There you have it, using the ComboBox or ListBox in VB .NET without ItemData. I hope that it proves to be of some help to someone out there. As usual, any questions can be sent via email.

All of the code on this page was formatted using the fabulous PrettyCode.Encoder