.Net application development specialists
asp.net, c#, vb.net, html, javascript, jquery, html, xhtml, css, oop, design patterns, sql server, mvc and much more
contact: admin@paxium.co.uk

Paxium is the company owned by myself, Dave Amour and used for providing IT contract development services including


  • Application development - Desktop, Web, Services - with Classic ASP, Asp.net WebForms, Asp.net MVC, Asp.net Core
  • Html, Css, JavaScript, jQuery, React, C#, SQL Server, Ado.net, Entity Framework, NHibernate, TDD, WebApi, GIT, IIS
  • Database schema design, implementation & ETL activities
  • Website design and hosting including email hosting
  • Training - typically one to one sessions
  • Reverse Engineering and documentation of undocumented systems
  • Code Reviews
  • Performance Tuning
  • Located in Cannock, Staffordshire
Rugeley Chess Club Buying Butler Cuckooland Katmaid Pet Sitting Services Roland Garros 60 60 Golf cement Technical Conformity Goofy MaggieBears Vacc Track Find Your Smart Phone eBate Taylors Poultry Services Lafarge Rebates System Codemasters Grid Game eBate DOFF

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 :

    <asp:DropDownList ID="Countries" runat="server">
        <asp:ListItem Value="1">France</asp:ListItem>
        <asp:ListItem Value="2">England</asp:ListItem>
        <asp:ListItem Value="3">Italy</asp:ListItem>
        <asp:ListItem Value="4">Spain</asp:ListItem>
    </asp:DropDownList>


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:

    public class Country
    {
        private int countryID;
        private string countryName;
 
        public int CountryID
        {
            get
            {
                return countryID;
            }
 
            set
            {
                countryID = value;
            }
        }
 
        public string CountryName
        {
            get
            {
                return countryName;
            }
 
            set
            {
                countryName = value;
            }
        }
 
        public Country(int countryID, string countryName)
        {
            this.countryID = countryID;
            this.countryName = countryName;
        }
    }


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

        private Dictionary<int, string> GetCountriesHashTable()
        {
            Dictionary<int, string> countries = new Dictionary<int, string>();
 
            countries.Add(1, "France");
            countries.Add(2, "England");
            countries.Add(3, "Italy");
            countries.Add(4, "Spain");
 
 
            return countries;
        }


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:

        private List<Country> GetCountries()
        {
            List<Country> countries = new List<Country>();
 
            Country france = new Country(1, "France");
            Country england = new Country(2, "England");
            Country italy = new Country(3, "Italy");
            Country spain = new Country(4, "Spain");
 
            countries.Add(france);
            countries.Add(england);
            countries.Add(italy);
            countries.Add(spain);
 
            return countries;
        }


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:

        private void MainForm_Load(object sender, EventArgs e)
        {
            Countries.DataSource = GetCountries();
            Countries.DisplayMember = "CountryName";
            Countries.ValueMember = "CountryID";
        }


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:

        private void OkButton_Click(object sender, EventArgs e)
        {
            string countryName = Countries.Text;
            int countryID = ((Country)Countries.SelectedItem).CountryID;
 
            MessageBox.Show(string.Format("The countryID is {0} which has a country name of {1}", countryID, countryName));
        }


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.