Binding a ComboBox to an IList and using SelectedValue

lc. picture lc. · Jan 7, 2009 · Viewed 8.2k times · Source

I have a ComboBox set up as follows, where KVPList is an IList (of KeyValuePair if it matters):

comboBox.DisplayMember = "Value";
comboBox.ValueMember = "Key";
comboBox.DataSource = KVPList;

I then have set up a binding with SelectedValue, binding to a BindingSource (to a DataSet). For whatever reason, the combo box always turns up blank when the form is displayed. It is properly populated, however (the values of the IList show up fine and can be selected).

Now, I've tried my best to trace through, and it appears to initially set the SelectedValue correctly when bound, but then somewhere along the way it gets reset to null. I've played with the order things get called as well, to no avail.

Can anyone shed some light on this or suggest a workaround?

For the record, on the same form, I have another ComboBox on the same form, with its SelectedValue bound to the same BindingSource. The DataSource is a DataSet, not an IList and it works like a charm. It might be an option to make a DataTable from the IList, but it seems like a whole lot of extra overhead; I'm generating the IList from an enumeration.

Answer

lc. picture lc. · Jan 7, 2009

Ouch. After basically half a day wasted on this one, I've figured it out. It was completely an error on my part.

The KVPList was set to an IList of KeyValuePair<short,string>, but the data field is of type int. Essentially, the databinding would fire, and set the SelectedValue property. Then the DisplayMember and ValueMember bindings would fire, checking the SelectedValue again. Since the ValueMember is of type short, not int, it wouldn't find a match and thus set it to null.

Something funny must be happening with boxing and unboxing, but I'm too tired to understand why right now.

I'll leave this question up in case someone else runs into the same issue. It's hard to track down because I would expect it to either try to cast or throw an exception, not silently go null. After all, short and int are both value types and last I checked (int)10 == (short)10 holds true.