Bind a ComboBox to a generic Dictionary
This is too cool.
Often you have a ComboBox (or ListBox) whose items you want to "bind" to a list of values. In the world of .NET 2.0 we have this funky new generic Dictionary collection, but there's a trick to using it to bind. Here's the code:
var choices = new Dictionary<string, string>(); choices["A"] = "Arthur"; choices["F"] = "Ford"; choices["T"] = "Trillian"; choices["Z"] = "Zaphod"; comboBox1.DataSource = new BindingSource(choices, null); comboBox1.DisplayMember = "Value"; comboBox1.ValueMember = "Key";
Now you can set comboBox1.SelectedValue = "F" and it will display "Ford"! How cool is that?

# Trackback from Talking About Speech on 17/05/2007 4:29 AM
# Trackback from Combo box datasource using Dictionary « Powertips on 9/03/2009 11:37 PM
Comments
# Compgumby
26/05/2006 6:49 AM
This is the balls. Thanks for the tip. :)
# Nick
20/07/2006 12:10 AM
Bless you. You are a gentleman and a scholar.
# Carlo
8/09/2006 5:17 PM
Fantastic, just what we needed. Can't believe there isn't a combobox.items.add(text, value) like in ASP.NET :(
# Brian
11/11/2006 6:17 AM
Well done - this is exactly what I needed. You just saved me an hour.
# Dapuzz
13/03/2007 9:13 AM
Very nice, and very simple.
Can you teach us what the 'null' means there?
# mabster
13/03/2007 9:53 AM
You mean the second parameter to "new BindingSource"?
I think that second parameter the name of the property (of the first parameter) that you want to bind to. In this example I don't want to bind to a single property - I want to bind to the whole collection - so I pass null as the second param.
Hope this helps!
# The_Assimilator
29/03/2007 5:25 PM
I couldn't find any help on binding to a Dictionary on MSDN and was about to start trying various things before I stumbled across this article - many thanks, you've saved me a lot of time!
A small note: binding this way with a Dictionary<TKey, TValue> may work, but using a SortedDictionary<TKey, TValue> does not. However, using a SortedList<TKey, TValue> does work.
I wish the collections classes in .NET were better named...
# mabster
29/03/2007 6:01 PM
You're very welcome, The_Assimilator! That's what I love about blogs - free sharing of information to help each other out!
# Koka
28/05/2007 5:11 AM
HEY MAN - U'RE GREAT!
1000% what I'va needed at the moment!
Thanks a lot! God Bless U!
# Kothandaram
20/07/2007 3:21 PM
Hi,
Thanks a alot fo rthe post.
I just want to know the namespace for the class - "BindingSource".
Thanks in Advance.
# mabster
20/07/2007 5:14 PM
msdn2.microsoft.com/.../system.windows.forms.bindingsource.aspx
# Román
22/08/2007 5:21 AM
Thanks so muuuuch ! ! !
this post was very helpfull for me :)
Román
from Argentine..
# Yudiyana
27/08/2007 5:46 PM
Thanks. cool code.
# Noshirwan Sheriyarji
31/08/2007 6:09 AM
Thanks a lot, this has cut down my time a lot.
Nosh
# matt
18/10/2007 1:45 PM
Thanks. helped me out lots. Much better than using a DataTable for binding when all u want is a name/value pair. cheers.
# Nick
18/12/2007 3:40 AM
I can't tell you how much this helped me. I've looked everywhere for info on binding to a Dictionary. I was about to give up and convert my code to a basic list. This rocks!
# Queego
22/12/2007 1:31 PM
Thanks so much, this works great! I was going nuts trying to bind a Dictionary(Of Integer, BigHairyCustomClass) to a combobox (which works just fine in ASP.Net, by the way) until I found your article.
One note for VB.Net users:
the line should be:
.DataSource = new BindingSource(ch, Nothing)
rather than this, which I tried first:
.DataSource = new BindingSource(ch, vbNull)
Thanks again!
# Visar Elmazi
14/01/2008 8:54 PM
I was just about to write something that achieves this... and Voilà!
you have a perfect solution.
# sklett
22/01/2008 2:11 PM
Exactly what I was looking for!
I think I love you!
# sklett
22/01/2008 2:24 PM
Here's a little helper method for binding an enum to a combo:
public static IDictionary<int, string> DictionaryFromEnum(Type enumType)
{
Array values = Enum.GetValues(enumType);
IDictionary<int, string> buffer = new Dictionary<int, string>(values.Length);
for (int i = 0; i < values.Length; i++)
{
object value = values.GetValue(i);
buffer.Add((int)value, value.ToString());
}
return buffer;
}
# mabster
22/01/2008 4:54 PM
Nice work sklett! I could envision that as an extension method on Enum, so I could simply say myEnum.ToDictionary().
# James
31/01/2008 3:18 PM
Thanks. However, I had to do something strange to get this to work in VS2008 / ASP.NET .... I had to add a reference to System.Windows.Forms to by web project?! in order to get access to the BindingSource namespace...
It works on my ASP.NET page using
.. code behind ...
DataList.DataSource = New BindingSource(nameDictionary,"")
DataList.DataBind()
... web page ...
<%#Container.DataItem.Key%>
<%#Container.DataItem.Value%>
# Vince
15/02/2008 10:47 AM
Saved me an hour, thanks
# alex
27/03/2008 1:51 AM
Hi
i need to convert WINFORM App. to ASP.NET 2.0
if it's good way to use class System.Windows.Forms.BindingSource in ASP.NET?
# mabster
27/03/2008 6:25 AM
Never done much ASP.NET, alex, so I can't help you there. Another reader might be able to though.
# question
29/03/2008 1:36 AM
Hi,
when you pass a null as second parameter, it throws an ArgumentNullException, anyway to get around that?
# Ray
9/04/2008 3:22 AM
I was getting the ArgumentNullException too. My mistake was the order of initialization. I was binding my combobox and then adding the dictionary items. Didn`t realize at first. It`s working well with SortedDictionary also, I haven`t encounter Assimilator`s problem. Thanks a lot mabster, very helpful!
# Metal Mike
10/04/2008 3:51 AM
I WAS KILLING MY SELF TRYING TO DO SOMETHING LIKE THIS. YOU ARE THE MAN!
# Dave Bonner
15/04/2008 9:38 PM
Excellent tip.
Ok here's a variant on this to bend your heads around.
I won't go into great depths explaining what I'm trying to do here otherwise this post will be about 20 pages long, but:
If I've got a dictionary of (string, someClass)
I want to use the keys in the dictionary as FIELDS for a datagrid, and have it pull out the values from the dictionary as the field values.
How would you go about doing THAT?
Cheers
# Soumya
18/04/2008 1:48 AM
Thank You very much sir..
You saved my time....It helped me..
# alex
16/06/2008 10:23 PM
cool. thnx
# cristian
29/07/2008 3:07 AM
Amazing! Thanks a lot.
Regards from Buenos Aires.
# Hans
30/09/2008 1:58 PM
Thanks to everyone!! All the info was very helpful!
From Chile!
# xr280xr
10/10/2008 4:58 AM
Your domain is appropriately named.
# beyond
6/11/2008 1:53 PM
thanks a lot!
Indeed, you are a genius!
a boy from china!
nice to meet u!
# Kevin C
1/12/2008 7:18 AM
How can I get the value of the selected item from a ComboBox bound like this?
# mabster
1/12/2008 7:24 AM
Just use SelectedValue, Kevin, and cast it back to the type you expect it to be.
So in my example, if I'd selected "Zaphod" then:
var key = (string)comboBox1.SelectedValue;
key == "Z"
# Kevin C
1/12/2008 7:44 AM
Thanks Matt!
Actually I also need the dictionary's Key value.
For binding I used:
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
Now comboBox1.SelectedValue gives me the dictionary value, but I can't seem to get the dictionary key. I tried comboBox1.SelectedText but it's empty.
# mabster
1/12/2008 7:54 AM
Ah ok so you've gone the other way around.
If you're using DisplayMember to represent the key in your dictionary then I guess you might be able to use SelectedItem. I *think* SelectedItem will return the key. Worst case is that it returns a KeyValuePair from which you can get either the key or the value.
# Kevin C
1/12/2008 7:59 AM
Perfect, thanks!
MessageBox.Show( ((KeyValuePair<string, string>)comboBox1.SelectedItem).Key );
# Robert
11/12/2008 5:20 AM
Very nice post. I was wondering: Is this possible at design-time?
I can make BindingSource1 the datasource of ComboBox1. But then the ValueMember and DisplayMember are empty (can't select anything).
I have to somehow 'bind' the dictionary to BindingSource1 (at designtime otherwise the DisplayMember and ValueMember are still not recognized)
# mabster
11/12/2008 7:27 AM
Visual Studio's design-time support for generics has always been very limited, so I'd be surprised if you can pull this off at design time, Robert. If you manage to get it going, drop me a note and I'll add it to the post!
# Ilia Jerebtsov
6/03/2009 9:59 PM
You can avoid the three ArgumentNullExceptions if you set the DataSource after creating the BindingSources:
BindingSource b = new BindingSource();
b.DataSource = choices;
comboBox1.DataSource = b;
or if you're using C# 3.0
comboBox1.DataSource = new BindingSource() { DataSource = choices; }
# SuparurkS
13/03/2009 2:34 AM
Just great! Simple and great solution.
# Ecthelion
20/03/2009 8:22 PM
Nice work! really helpful!!! Thx a lot for sharing.
# Brad
1/04/2009 6:53 AM
Thanks. Perfect! It's just what I've been looking for!
# S. Davy
22/05/2009 4:30 PM
Thank you! This is exactly what I was looking for. :-)
# Mike
16/06/2009 11:47 AM
Thanks for leaving this post online!
# moncy
24/06/2009 12:03 AM
this helps to solve my big issue..thanks
Leave a Comment