tags:

views:

1423

answers:

5

Hey guys / gals,

I have a question that I am shocked I haven't had a need to ask before. I am mostly an ASP.net developer but I am trying to work 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

Thanks and sorry for the newb question :)

+3  A: 

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.

SLaks
Is there a way to accomplish this without databinding? I am manually adding items to the combobox.
nokturnal
combobox.Items.Add
Forgotten Semicolon
If you set the ValueMember / DisplayMember properties of the combobox you do not need to databind. It will should use them even if you use the combobox.Add(yourobject); The catch is that you still need a name/value object.
Joshua Cauble
+3  A: 

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;
Marc Gravell
I had no idea the combobox was so powerful... I utilized this solution as I am a Linq newb as well and decided to go down this road. Stackoverflow rules, thanks guys!
nokturnal
+4  A: 

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.

nasufara
Why are you calling `ToString` on a string?
SLaks
+1  A: 

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.

CSharpAtl
+2  A: 

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";
    }
Jamie Ide
Hi how do you do this in VB, I have no error in compile time but I have error in runtime
geocine