Page 1 of 1

ComboBox DisplayMember and ValueMember [WinForms] Rate Topic: -----

#1 andrewsw  Icon User is offline

  • I'm a doctor and want my sausages
  • member icon

Reputation: 6322
  • View blog
  • Posts: 25,439
  • Joined: 12-December 12

Posted 10 June 2015 - 11:25 AM

This tutorial demonstrates how to display a value in a ComboBox, but to then retrieve a different value when the user makes a selection.

A very common example is to display a list of shopping items, and then obtain the price of the item that the user has selected. A simplistic first approach is to concatenate the item and price Item & " " & CStr(Price) and manually Add each of these strings to the ComboBox. This quickly becomes messy because you then have to de-construct this string to extract the Price, and you may not want the Prices visible in the ComboBox. (This approach also won't help if your ComboBox represents more complex objects.)

Create a Form with a ComboBox named cboPerson.

Create a Class to hold (to encapsulate) the values we need:
    Class Person
        Property FirstName As String
        Property Age As Integer
    End Class

(The full code appears further down.)
Option Strict On

Public Class Form1
    Private _people As New List(Of Person)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        _people.Add(New Person With {.FirstName = "Bob", .Age = 23})
        _people.Add(New Person With {.FirstName = "Fred", .Age = 24})

We create and populate a List(Of Person).

Still in the Load event:
        cboPerson.DataSource = _people
        cboPerson.DisplayMember = "FirstName"
        cboPerson.ValueMember = "Age"
    End Sub

The DataSource is set to our List. With data from a database you would first Fill a DataSet and set the DataSource to a DataTable of the DataSet.

The DisplayMember states which property will be displayed in the ComboBox. With a database this would be a column from a DataTable.

The ValueMember states what value the user has selected, accessible as the ComboBox's SelectedValue. Again, with a database, this would be a column from a DataTable.
    Private Sub cboPerson_SelectionchangeCommitted(sender As Object, e As EventArgs) Handles cboPerson.SelectionchangeCommitted
        If cboPerson.SelectedIndex <> -1 Then
            MessageBox.Show(cboPerson.SelectedValue.ToString())
        End If
    End Sub


This code proves that it works. When the user selects a Person a MessageBox confirms their chosen value, the Person's Age. (I'm ignoring an index of -1, which would mean there isn't an item selected.)



I'm using the SelectionchangeCommitted event because, if using SelectedIndexChanged or SelectedValueChanged, the MessageBox will display several times when the form first loads, one for each Person in our List. SelectionchangeCommitted only fires when the user makes a selection:

MSDN said:

Occurs when the user changes the selected item and that change is displayed in the ComboBox.



There are important concepts demonstrated here. Particularly, how to bind a UI element (a ComboBox) to objects (class instances) that we create. As I've indicated, the process is not that dissimilar if a database is involved.

The full code:
Option Strict On

Public Class Form1
    Private _people As New List(Of Person)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        _people.Add(New Person With {.FirstName = "Bob", .Age = 23})
        _people.Add(New Person With {.FirstName = "Fred", .Age = 24})

        cboPerson.DataSource = _people
        cboPerson.DisplayMember = "FirstName"
        cboPerson.ValueMember = "Age"
    End Sub

    Private Sub cboPerson_SelectionchangeCommitted(sender As Object, e As EventArgs) Handles cboPerson.SelectionchangeCommitted
        If cboPerson.SelectedIndex <> -1 Then
            MessageBox.Show(cboPerson.SelectedValue.ToString())
        End If
    End Sub

    Class Person
        Property FirstName As String
        Property Age As Integer
    End Class
End Class




We aren't restricted to two values though. SelectedItem gives us access to the Person instance, so we can use this to retrieve other values/properties. Add a new Property:
    Class Person
        Property FirstName As String
        Property Age As Integer
        Property NickName As String
    End Class


In the load event:
        _people.Add(New Person With {.FirstName = "Bob", .Age = 23, .NickName = "Bobby"})
        _people.Add(New Person With {.FirstName = "Fred", .Age = 24, .NickName = "Freddy"})


We can then display the NickName, and access any other properties we need:
    Private Sub cboPerson_SelectionchangeCommitted(sender As Object, e As EventArgs) Handles cboPerson.SelectionchangeCommitted
        If cboPerson.SelectedIndex <> -1 Then
            'MessageBox.Show(cboPerson.SelectedValue.ToString())
            MessageBox.Show(CType(cboPerson.SelectedItem, Person).NickName)
        End If
    End Sub


SelectedItem gives a fuller picture of how data binding works in WinForms.

This post has been edited by andrewsw: 10 June 2015 - 12:42 PM


Is This A Good Question/Topic? 4
  • +

Page 1 of 1