ComboBox Text and Numeric Values
If you are like me and started out in the world of .net with asp.net first and then had a with WinForms afterwards then you may be frustrated by how difficult some things are to do within WinForms which are relativeley easy in asp.net. Working with the Combobox is one of these experiences which I have definatley had myself and judging by a flick through Google, many other people have had simillar experiences.
So I had a tinker myself and thought I would document my findings which while not exhaustive, will give you a little insight and some practical tips on how to work with the Combobox in a WinForms environment.
One of the most common things we do in asp.net is populate a DropDownList by binding it to a data source. This might be a DataTable, DataSet, Collection of Custom objects etc to name a few. These would typically come via a database and we might have data like this:
1 France
2 England
3 Italy
4 Spain
So what you want is for your Combobox to display the textual country names, but to get a hold of the corresponding numerical value when one is selected - typically this numerical value will come from a database and will need storing back into a database as a foreign key maybe.
So in asp.net we could just :
Or we could databind to some object such as a DataSet, DataTable, Collection of Custom Objects etc and it was all really easy.
In Winforms though if you look at the DataSource property of the ComboBox class then you will see it is defined as an object and so we can assign a collection of custom objects to the ComboBox. So first let us create a custom class to represent a Country which will look like this:
Now if you create a little WinForms app with just a combobox in and try and data bind to the following data source by just using combobox1.DataSource = GetCountriesHashTable() lets see what happens
countries.Add(2, "England");
countries.Add(3, "Italy");
countries.Add(4, "Spain");
What will actually happen when you run this is that it will not work and you will receive an error which will say:
Complex DataBinding accepts as a data source either an IList or an IListSource.
So what this is saying is that the object we data bind to must implement either the IList or IListSource interface. So all we need to do is write our method differently so that rather than returning a Hashtable, it return some other object which does implement one of those interfaces. Now I won't pretend to know all classes which do but certainly the generic List does so lets with that and change our data source method to look like this:
Now of course this data would really be coming from a database usually but no need to do that for this demonstration. What you now need to do is to set this method as the datasource of your Combobox and also specify which properties we will use for display and which we will use for underlying values.
This is achieved as follows:
So now when we choose a value from the drop down list we are able to access both the text value and the underlying numerical value as follows:
And that's it! So not as easy as asp.net, but still easy enough once you know how. Interestingly I have seen articles where someone has added objects to their Combobox of type System.Web.UI.WebControls.ListItem!
Now to do this you would need to add a reference so this isn't a clean solution but hey if it works, maybe it shows that the ListItem has just been placed in the wrong namespace by Microsoft!
Questions and comments appreciated as usual via the form below.