Oh, here's a fun one.
I have a list of locations that I'm retrieving from a web service, and I want to display them in a ComboBox. I also want to have a blank entry at the top of the list, so "nothing" can be selected. While I'm sure there are ways to do this with less code, creating binding objects and such (especially since the retrieved object list is already pre-sorted in the order I want), I've resorted to just creating a DataTable with an ID and display column and copying the values I want into it. It does make things easier when I have one combo box filter another, as DataTables already have code written for searching and filtering.
Anyway, after I get my data, I have a DataTable that looks like this:
LocationId | Location |
---|---|
DBNull.Value | String.Empty |
2 | Aurora |
7 | Colorado Springs |
1 | Denver |
3 | Ft. Collins |
4 | Longmont |
6 | Parker |
Now, I bind it to my ComboBox like this:
combo1.DataSource = dataTable;
combo1.DisplayMember = "Location";
combo1.ValueMember = "LocationId";
Note that you have to set the DataSource first and the DisplayMember & ValueMember properties second, otherwise you get a ComboBox full of "System.Data.DataRow". Nice.
Now, on this form, when a value is selected, the selected value is used to filter another list; and, when the form is submitted, the selected value is passed off to a web service. How do you find out when a value is selected, and what that value is? Simple; bind to the SelectedValueChanged
event, and query the SelectedValue property, right? In theory.
In practice, no. To make a long story short, I dropped a label onto the form so I could see what was going on in "real time". First, the code:
private void combo1_SelectedValueChanged(object sender, EventArgs e) {
label1.Text = Convert.ToString(combo1.SelectedValue) + " - " + Convert.ToString(((System.Data.DataRowView)(combo1.SelectedItem))["LocationId"]);
}
And the results:
ComboBox selection | Label1.Text |
---|---|
empty | - |
Aurora | 1 - 2 |
Colorado Springs | 2 - 7 |
Denver | 3 - 1 |
Ft. Collins | 4 - 3 |
Longmont | 6 - 4 |
Parker | 7 - 6 |
Incidentally, the SelectedText property was always blank.
On the up-side, as you can see, I found a way to get the real value (using the SelectedItem and casting appropriately). On the down-side, it means I have to use that construction to get the selected value on this and every other similar ComboBox (there are actually four on this form alone), since SelectedValue, apparently, doesn't.