How to create a Winforms Combobox with Label and Value?

Viewed 57031

I am mostly an ASP.NET developer but I am working on a WinForms app and noticed a large difference between the ASP.NET combobox (html select) and that of WinForms. I found (maybe incorrectly so) that WinForm's combobox only has a "label" whereas ASP.NET allows you to specify a "label" and a "value".

I am looking to use a WinForms combobox (or another comparable control) with a label and a value (Foobar / 42329). Is this possible? I have attempted to search for the answer but haven't come up with much. If there is no way to accomplish that, how does one go ahead and design a WinForm combobox that would represent say Cities with their associated database id?

  • Toronto / 2324
  • Montreal / 64547
  • Vancouver / 1213
6 Answers

I can think of a few ways:

  • override the ToString() of a City class to return Name + " / " + Id;
  • ditto, but with a TypeConverter
  • add a DisplayText property that return the same, and use DisplayMember
  • build a shim class for the data

For the last:

var data = cities.Select(city => new {
     Id = city.Id, Text = city.Name + " / " + city.Id }).ToList();
cbo.ValueMember = "Id";
cbo.DisplayMember = "Text";
cbo.DataSource = data;

Assuming that your values are unique, you can first populate a dictionary then bind the combobox to the dictionary. Unfortunately databinding requires an IList or an IListSource so you have to wrap it in Binding Source. I found the solution here.

    private void PopulateComboBox()
    {
        var dict = new Dictionary<int, string>();
        dict.Add(2324, "Toronto");
        dict.Add(64547, "Vancouver");
        dict.Add(42329, "Foobar");

        comboBox1.DataSource = new BindingSource(dict, null);
        comboBox1.DisplayMember = "Value";
        comboBox1.ValueMember = "Key";
    }

You could try creating a small class called ComboBoxItem, like so:

public class ComboBoxItem<T>
{
    public string Label { get; set; }
    public T Value { get; set; }

    public override string ToString()
    {
        return Label ?? string.Empty;
    }
}

And then when you need to get an object, just cast it to a ComboBoxItem.

A ComboBox can be bound to a collection of objects by setting its DataSource property.

By default, the SelectedValue property will be give the object that was selected, and the list will call ToString on each object and display the result.
However, if you set the DisplayMember property of the ComboBox, it will display the value of the property named in DisplayMember in the list. Similarly, you can set the ValueMember property of the ComboBox and the SelectedValue proeprty will return the value of the property named by ValueMember.


Therefore, you need to bind the ComboBox to a list of objects that have Name and Value properties.
You can then set the ComboBox's [DisplayMember property to Name and ValueMember property to Value.

EDIT: You can also call the Add method and give it such an object instead of databinding. Alternatively, you could bind it to a List<T> or an array.

There is a property called DisplayMember = name of property whose value will be used for display, and ValueMember which is the property of the to use for the value.

Related