Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# ComboBox with Text and Value [duplicate]

Tags:

Possible Duplicate:
C# Winforms Combobox with Label and Value

How would one approach storing a display value and a real value in a ComboBox?

Ie, the ComboBox displays:

  • Destroy World
  • Fire Slingshot
  • Summon Cthulhu

but the values as retrieved are:

  • dw
  • ss
  • sc

I want to be able to retrieve the value of the selected item in a way similar to this:

string selectedValue = combobox1.SelectedValue

Updated code in response to answers:

Dictionary<string, string> filterItems = new Dictionary<string, string>
{
    {"Destroy World", "dw"},
    {"Fire Slingshot", "fs"},
    {"Summon Cthulu", "sc"},
};
this.options_filterby.DataSource = new BindingSource(filterItems, null);
this.options_filterby.DisplayMember = "Key";
this.options_filterby.ValueMember = "Value";

Now for some reason, although the DisplayMembers are absolutely fine, the ValueMembers return dictionary objects. Even stranger, after a while, eventually the ValueMembers will return strings as expected.

private void options_filterby_SelectedIndexChanged(object sender, EventArgs e)
{
    MessageBox.Show(options_filterby.SelectedValue.ToString());
}

This returns dictionaries for the first few times I change the selected item of the ComboBox, but eventually returns strings as needed.

Update: fixed (can't add as solution because question was closed)

In response to the above problem, the fix is to set the DisplayMember and ValueMember properties before the DataSource. I presume this is a bug. The code should read:

this.options_filterby.DisplayMember = "Key";
this.options_filterby.ValueMember = "Value";
this.options_filterby.DataSource = new BindingSource(filterItems, null);
like image 474
Chris Watts Avatar asked Apr 08 '12 12:04

Chris Watts


1 Answers

You use the DisplayMember and ValueMember to determine what the ComboBox will display, and what will be returned from SelectedValue. When you set the DataSource property, the ComboBox will use the property described by DisplayMember to render a string to the user.

  • DataSource
  • DisplayMember
  • ValueMember

Something like this

public class Item {
  string Name { get; set; }
  string Value { get; set; }
}

ComboBox box = new ComboBox();
box.DisplayMember = "Name";
box.ValueMember = "Value";
box.DataSource = new [] { new Item() { "Test", "test" } };

If you don't set ValueMember the actual Item is returned instead, and if you don't set DisplayMember, the items ToString() method will be used to get the string presented to the user.


I'm not sure if this will work or if it may change what you have, but you could try it at least :) The thing is, I'm not certain what BindingSource does when it gets a dictionary as its datasource. I suppose it treats it as an IEnumerable<KeyValuePair<>> though, so your code should work, but well, it doesn't, so perhaps this will..

BindingSource source = new BindingSource();
source.DataSource = typeof(KeyValuePair<string, string>);
foreach (KeyValuePair<string, string> pair in filterItems) {
    source.Add(pair);
}
options_filterby = source;
like image 159
Patrick Avatar answered Oct 07 '22 19:10

Patrick