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
# Trackback from Ein Dictionary als DataSource on 24/08/2010 7:44 AM
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
# Shilesh Rastogi
28/07/2009 7:54 PM
Thanks for the great tip, this post has helped a lot.
# Josue
24/09/2009 6:28 AM
jeje, Simply but usseful
# Drew
21/11/2009 6:12 AM
thanks mate you nailed exactly what I was trying to do
# scottie
28/01/2010 12:49 AM
superb - fixed my problem thanx!
# LEo
20/03/2010 2:33 AM
It works for me, but it isn't dynamic. If I add elements to the dictionary, the Listbox doesn't get updated. Any ideas?
# mabster
20/03/2010 8:19 AM
LEo - Dictionary doesn't support change notifications like a BindingList does, so the ComboBox won't know when the dictionary gets modified. I don't know of any good way around that other than re-binding the ComboBox.
# gijeet
29/04/2010 4:14 AM
I have a problem in winforms. when I set the combobox datasource, it fires off the SelectedIndexChanged event. Not good. Tell me now to prevent that and I'll give you accolades. Combobox's suck in winforms. Can't use Items.AddRange(MyDictionary) or Items.Add(MyDict.Key, MyDict.Value).
# mabster
29/04/2010 9:25 AM
gijeet - hook up your SelectedIndexChanged event in code after you've set the DataSource property. If necessary, *unhook* it beforehand.
# GiJeet
1/05/2010 7:28 AM
The hookup of the events is in the InitializeComponents section which you can't modify or your changes will just get overwritten. So, are you suggesting to unhook the event in the code block that you bind the control then re-hook it back up again after you bind? Please provide an example so I understand what you're suggesting. Thanks!
# mabster
3/05/2010 11:47 AM
@GiJeet - don't hook your event handler up at design time at all. That way you don't have to unhook it. Then do it in code, like this:
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
Obviously your ComboBox's name and the name of the event handler method will probably be different, but that's the syntax.
# Rainer
17/05/2010 1:07 PM
Thank you for the tip!
Mabster, if you change the order of the assignments, then the comboBox1.SelectedValue will be accessible with the appropriate Dictionary Key:
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
comboBox1.DataSource = new BindingSource(choices, null);
# Xilmiki
5/08/2010 7:52 PM
The best! great tip
# r3x
17/08/2010 9:51 PM
thanks! :-)
# sachi
6/09/2010 10:17 PM
Thanks
# Hi
23/09/2010 10:40 PM
I am using VB.NET on winforms. I get a 'value cannot be null' exception on this
LvName.DataSource = New BindingSource(itemValue, Nothing)
# Mayank Dhulekar
6/10/2010 7:00 PM
Awesome man...thanks alottt.....
# James
16/11/2010 8:22 AM
Thank you!
# Roger
24/05/2011 4:35 AM
Thank you. Very nice.
# AK
15/06/2011 3:16 AM
such a nice post. Easy to understand. Thanks you very much.
# anil
16/09/2011 3:20 PM
Very cool !!
# Ermano
24/11/2011 12:40 PM
Awsome !!!
# Justin
24/12/2011 2:16 AM
Thankyou
# Kartik
30/12/2011 8:57 PM
Lovely - helped me out of a bigg messsssssss Thanks
# Pablo Alejandro Perez Acosta
18/01/2012 7:35 AM
Thank you
# Denis
2/03/2012 2:42 AM
thx u very much,tusen takk,spasibo ...
# Shivam Shukla
4/07/2012 3:28 PM
Thnnx..#mabster..really it is of great help for me...saved ma time ...thanx again for such a post...!
# Vishwajeet
4/07/2012 3:33 PM
wow mabster... what the code!!!!!! it helped me a lot in my practice....
u r a gem... good work...
thanks.....
# darrylqa
28/11/2013 9:09 AM
Thanks for posting this. It helped me.
# lethalmarc
10/02/2014 6:37 PM
populating combobox values from database values
vb.net-informations.com/.../bind-combobox.h
vb.net tutorial