Introduction

This article will teach you how to use data binding with ComboBoxes. It walks you through the following examples:

Displays a string value and binds to a string value, all bindings in XAML. The ComboBox items collection is defined as a StaticResource in the application resources in the App.xaml.

Displays a string value and binds to an enum value, all bindings in XAML. The ComboBox items collection is defined as a list in the code behind file. In addition, this technique provides an easy way to get friendly translatable names for enums.

These two examples will cover the basics on how to get data binding to work with ComboBoxes.

Background

There are many articles on the web that cover the topic of data binding. So why write another one? Good question. ComboBoxes have complications that don’t exist when you are binding to a control like a TextBox. With all of the articles out there, when I was trying to use a ComboBox for the first time, I didn't find a single article that clearly explained how to bind a ComboBox. In addition, I found many questions that didn't have complete answers. After finally figuring out how to get things to work, I decided to share my findings. The main difference with data binding and ComboBoxes are that there are actually 4 bindings that have to be set. This article walks you through, step by step, how to get each of the 4 data bindings to work with ComboBoxes.

Before jumping into working with ComboBoxes, I recommend you first read and understand the basics of data binding. Josh Smith has published several excellent articles on this subject here on CodeProject. This one, A Guided Tour of WPF – Part 3 (Data binding), does an excellent job of explaining the basics of data binding. This one, Moving Toward WPF Data Binding One Step at a Time, walks you through getting data binding working with a TextBox. It is important to understand the basics covered in these articles before you try and tackle data binding with ComboBoxes.

The Examples in the Demo Application

This article covers the important points of data binding with ComboBox's in two separate examples. The second example builds off the first, so make sure you check out both examples to get a full understanding of this topic.

Databinding ComboBox Example #1

This example:

Displays a string value and binds to a string value.

All bindings are done in XAML.

The ComboBox items collection is defined as an application resource in the App.xaml file.

Note: The TextBlock beneath the ComboBox is bound to the same property as the ComboBox to prove the data binding is working. When you select a new value in the ComboBox the data object will be updated, it will send a property changed notification, the TextBlock will receive the property changed notification and it will be updated also.

Before looking at the bindings of the ComboBox, let's look at what we are going to be filling it with. First we create an array of three objects, of type ComboBoxItemString (which is a class defined in this project).The objects ValueString properties are set to: Red, Green, and Blue respectively.This collection is defined as a StaticResource in the application resources in the App.xaml file like this:

Now let's look at the ComboItemString class we are using above. It is defined in this project like this:

namespace ComboBoxDataBindingExamples
{
/// This class provides us with an object to fill a ComboBox with
/// that can be bound to string fields in the binding object.
publicclass ComboBoxItemString
{
publicstring ValueString { get; set; }
}
}

You can't get a much simpler class than this. All it has is one public property called ValueString of type string. So why is it needed?

This is where things get interesting, read this carefully. In order for data binding to work correctly, you need a 'property' to bind to. If we had an array of strings what property would we bind to? There aren't any. The only property on the string class is 'Length' and we don't want to bind to that. This is one of the issues that confused me when I first started trying to bind ComboBoxes. To make matters more confusing, you can use an array of strings to populate the ComboBox list if you don't use data binding. The reason that works is the ToString method is called to get the display value of the object. That's okay until you try to bind to it, that's when it doesn't work.

Let me repeat this because it is important, in order for data binding to work, you MUST bind to a PROPERTY on an object. The ComboBoxItemString class provides us with a property 'ValueString' to bind to.

Now let's look at the ComboBox definition in the XAML file. Here it is:

The ComboBox has four properties that are set. Let's look at them one at a time.

ItemsSource - is bound to the static resource array 'ColorListString' that we defined above as an application resource in the App.xaml file. This list of items is used to populate the Items collection of the ComboBox. This collection is used to generate the items that show up in the dropdown list.

DisplayMemberPath - is bound to the ValueString property of the ComboBoxItemString object, in the ItemsSource list. When an item is selected from the dropdown list, this is the value that is displayed to the user.

SelectedValuePath - is bound to ValueString property of the ComboBoxItemString object, in the ItemsSource list. When an item is selected from the dropdown list, this is the property used to get the value to set the SelectedItem value to.

SelectedValue - is bound using a property binding of "{Binding ColorString}". When an item is selected in the list, this is the property on the data object that is set to the value returned from the SelectedValuePath property.

Looking at the binding above, you might think that the DisplayMemberPath and the SelectedValuePath are redundant since they bind to the same property, but they aren't. In the next example, you will see that we make use of the fact that these properties can be bound to two different values. Stay tuned.

But there are still two missing pieces. Do you know what they are? One of them is we haven't defined the data object we will be binding to and the other is that we haven't set the DataContext yet. All data binding are based on binding to a property on an object. The DataContext must be set to the object that contains the property you want to bind.

So what object are we bound to? Let's take a look. The rest is done in the code behind file. Here it is:

Could it be that this is the entire code behind file? It is except for some comments. This file only does a couple of things. Let's look at them one at a time.

It has a private member viewModelString object which it assigns to a new instance of the ViewModelString class.

The DataContext is set to be the viewModelString member that is part of this class. This means that the ComboBox's SelectedValue property binding is going to bind to a property called 'ColorString' on the ViewModelString class.

Ok, but what does the ViewModelString object look like. This is the final piece, hang in there. We know it has to have a public property called 'ColorString' or our binding won't work. Here is the entire ViewModelString class.

A void constructor so the class can be used as an object element in the XAML.

A string property, named 'ColorString', that is used to do the data binding to the ComboBox.

A NotifyPropertyChanged property which is required in order to get your bindings to work.

That's it. That wasn't that bad, was it.

Now we will build on this example by adding a few additional twists.

Databinding ComboBox Example #2

This example:

Displays a string value and binds to an enum value.

All binding are done in XAML.

The ComboBox items collection is defined as a list in the code behind file.

This technique also provides an easy way to get friendly translatable names for enums.

Note: The TextBlock beneath the ComboBox is bound to the same property as the ComboBox to prove the data binding is working. When you select a new value in the ComboBox the data object will be updated, it will send a property changed notification, the TextBlock will receive the property changed notification and it will be updated as well.

Just like in the first example, we need to create an array of objects to display in ComboBox. This time, we will create the list in the code behind file since it introduces a different twist when dealing with the bindings. We'll look at this in more detail a little later.This is what the code looks like:

// Set up the collection properties used to bind the ItemsSource
// properties to display the list of items in the dropdown lists.
// The string values are loaded from the resource file which can
// be translated into other languages.
ColorListEnum = new List<ComboBoxItemColor>()
{
new ComboBoxItemColor(){ ValueColorEnum = ViewModelEnum.Colors.Red,
ValueColorString = Properties.Resources.RedText },
new ComboBoxItemColor(){ ValueColorEnum = ViewModelEnum.Colors.Green,
ValueColorString = Properties.Resources.GreenText },
new ComboBoxItemColor(){ ValueColorEnum = ViewModelEnum.Colors.Blue,
ValueColorString = Properties.Resources.BlueText },
};

As you can see ,we are using a different object in this list than what we used in the first example. Let's take a look at the ComboBoxItemColor class we are using above. It is defined in this project like this:

namespace ComboBoxDataBindingExamples
{
/// This class provides us with an object to fill a ComboBox with
/// that can be bound to 'ViewModelEnum.Colors' enum fields in the binding
/// object while displaying a string values in the to user in the ComboBox.
publicclass ComboBoxItemColor
{
public ViewModelEnum.Colors ValueColorEnum { get; set; }
publicstring ValueColorString { get; set; }
}
}

Just like in the previous example, this is a very simple class. This class has two public properties called ValueColorString (type string) and ValueColorEnum (type ViewModelEnum.Colors). Since we want to display a string value and bind to an enum value, we need these two properties.

Now let's look at the ComboBox definition in the XAML file. Here it is:

Do you notice anything different about these bindings compared to the first example? There are some important differences. Let's look at them one at a time.

ItemsSource - is bound using a property binding of "{Binding ColorListEnum}". In the previous example, we had bound this to a static resource.

DisplayMemberPath - is bound to the ValueColorString property of the ComboBoxItemEnum object, in the ItemsSource list. Similar to the last example.

SelectedValuePath - is bound to the ValueColorEnum property of the ComboBoxItemString object, in the ItemsSource list. This is different than it was in the last example. We are binding to a different property than the DisplayMemberPath. This binding sets the SelectedItem to be the enum value while the display value is the string value. This explains why there are two properties.

SelectedValue - is bound using a property binding of "{Binding ViewModelEnum.ColorEnum}". At first glance, this might look similar to the first example, but there is an important difference. Do you see it? In this example, we are binding to a property (ColorEnum) of a property (ViewModelEnum), but why? The answer has to do with the change to our ItemsSource binding and a change to our DataContext, keep reading.

Just like in the first example, the rest is done in the code behind file. Here it is:

using System.Windows;
using System.Collections.Generic;
namespace ComboBoxDataBindingExamples
{
publicpartialclass Example2Window : Window
{
// Collection property used to fill the ComboBox with a list
// of ComboBoxItemColor objects that contain colors options.
public List<ComboBoxItemColor> ColorListEnum { get; set; }
// Object to bind the combobox selections to.
public ViewModelEnum ViewModelEnum { get; set; }
private ViewModelEnum viewModelEnum = new ViewModelEnum();
public Example2Window()
{
// Set the property to be used for the data binding to and from
// the ComboBox's.
ViewModelEnum = viewModelEnum;
// Set up the collection properties used to bind the ItemsSource
// properties to display the list of items in the dropdown lists.
// The string values are loaded from the resource file which can
// be translated into other languages.
ColorListEnum = new List<ComboBoxItemColor>()
{
new ComboBoxItemColor(){ ValueColorEnum = ViewModelEnum.Colors.Red,
ValueColorString = Properties.Resources.RedText },
new ComboBoxItemColor(){ ValueColorEnum = ViewModelEnum.Colors.Green,
ValueColorString = Properties.Resources.GreenText },
new ComboBoxItemColor(){ ValueColorEnum = ViewModelEnum.Colors.Blue,
ValueColorString = Properties.Resources.BlueText },
};
// Set the data context for this window.
DataContext = this;
// Init the window
InitializeComponent();
}
}
}

This class is a lot different than in the first example. Let's look at things one at a time.

ColorListEnum- This property is the property the ItemsSource binds to. This replaces the StaticResource. It is sometimes useful to be able to bind to a collection that is defined in code behind. This is how you do it. Notice that this is a property and not a data member, this enables the binding.

ViewModelEnum- The SelectedValue property binds to the ColorEnum property through this property. Notice the SelectedValue binding is set to "{Binding ViewModelEnum.ColorEnum}". In this case, we are binding to a property of a property.

viewModelEnum- This is the data member the above property is set to. Remember you cannot bind directly to a data member.

ColorListEnum- is initialized to a List containing three ComboBoxItemColor objects. This is equivalent to the static resource in the first example.

DataContext - is set to this window.

Wait a minute. In the first example, the DataContext was set to the view model class. Couldn't we have done that here. No we couldn't. Can you figure out why? It's because we are NOT binding the ItemsSource to a static resource. Confused yet? It was the first time I tried this.

This is one of the most confusing parts of data binding and ComboBox's. Let's walk through it slowly. You only have one DataContext for a ComboBox, or any other control for that matter. This means (if your ItemsSource is being bound to a code behind property) that the DataContext of your ComboBox must contain two properties for your ComboBox to bind to. The first property is for your ItemsSource collection (in this case ColorListEnum) and a second property for your SelectedValue property (in this the ColorEnum property on the ViewModelEnum property). This is an important difference when binding a ComboBox versus a simple control like a TextBox.

Now we will take a look at the ViewModelEnum class. Here it is in its entirety.

I needed a two-way bound combobox with images and text. I accomplished it and have modified your example. My need was for an audio DSP crossover selection for slope. Each combobox item needed text and a png image.
I also wanted to have multiple combo boxes with multiple instances of the bound data object.

all the examples I've found are of "binding" "data" to combobox controls involve static data, very easy, however I don't actually call literals and other non-dynamic information as "data" binding and data are terms reserved for dynamic data that is constantly moving and changing. I find it very easy to display static data in a combo box, where are the connection strings to the database?

While your example is good for a very simple ComboBox example, it has some misleading information. Contrary to popular belief, INotifyPropertyChanged is NOT necessary in either of your examples to get them to work. Comment its implementation to validate that statement.

Where it would be useful, is if you had code behind that changed the selected value (such as a button that selected a new value in the ComboBox).

PropertyChanged events work from the code behind to the UI thread (Xaml generated code) which has an event handler subscription for the event fired. This will then update the UI to display the new value. In essence Property notification works in one direction from code behind to UI, and is not needed in the other direction (UI to code behind update of the property).

Great article, any help with WPF is appreciated, sometimes it looks more simple to make new user control in WinForms then set up the bindings that you need, i still can understand why WPF is made as it is, too complicated and all the time it distracts you from the main logic.
Also i have a problem with binding properties from user control to ComboBox, they are binded in the drop down list, but the selected item is never shown, I use different template for SelectedItim and DropDownList.
Does this rings any bells?

I am trying to update 2 data columns using a combobox. I have 2 tables. I am programing in C# xaml and Silverlight 5 Ria Services. SQL DB.

Member Table:

Id

Name

Event Table:

EventId

MemberId

MemberName

My New Event form has a combox which shows the member name from the members table. It also binds to the Id value of the members table. When I select a member I am able to bind to the EventTable MemberId and update the value for a new event.

What I need to happen is to update both the MemberId and MemberName fields. Currently when I select a member only the MemberId column is updated. I need the MemberName column to be updated as well.

I am finding it difficult to update BOTH the MemberId and MemberName colums in the Event Table when selecting a member from the Combobox. Can someone please provide guidance on how to achieve this intended functionality with the combobox , or by some other means.

I'm trying to understand your article. I get stuck already on the first example. Where is the class ComboBoxItemString? Cannot find it in the download. And there is a typing error in the first code: instead of

Hi! Let me start by saying how thankful I was for your fine article. I was completely stuck, but you got me back on track. I've written a related article that, among other details, thanks you for your fine work.

I'm guessing that a number of your readers will prefer my solution to yours, but in either case I'd recommend that they read your first.

Hi Steve,
in code behind you are referencing a ViewModelString class but the referenced class is actually named "ViewModel". Could be a little confusing for beginners like me.

I 'm still struggling with making your example 1 run. What makes me headache is that my textblock.Text property is not actualised after choosing another ComboBox value. It is really a most complicated concept.
Thanks for your examples,
elmar

I find it rather annoying to write so much code behind to have something as basic as combobox working. To me it seems that the WPF designers have gone astray with their approach... A good library is supposed to make one write less code, not the opposite.

I agree - I think the WPF designers have gone astray. must be design by a LARGE committee. I've been fighting my way through adding a simple combo box that will have an unchanging list of values in it (WPF/xaml and c#), and am longing now for the old days of C++ and MFC - I might have had to setup everything myself, but at least there were no 'magically' working or not/never working bindings. (cripes)

Thanks, your article helped me indirectly by motivating me to start over from scratch and keep things simple. I was having trouble with binding the SelectedItem or SelectedValue property. My intention was to bind SelectedItem to a property designed to get and set an instance of the same class that is used to populate the combo box. This turned out to be a valid intention, and when one takes that approach, it is not necessary to set SelectedValuePath. I still don't know why I was having trouble with the binding, but beginning again with a clean slate somehow solved my problem. ComboBox IS rather finicky.

There is an algorithm called next_permutation which given a range will return true on each subsequent call until all permutations have been encountered. Works not only on strings but on any "sequence" type.
http://www.dapfor.com/en/net-suite/net-grid/tutorial/data-binding

Sacha, thanks for commenting on my article. I have read many of your articles on CodeProject (all of them 5 star in my opinion) and am happy to receive any input you have to offer. Your solution obviously works but as you point out in the article it uses reflection, a type converter, and an attribute class. For this article I was trying to focus more on data binding issues. I encourage everyone to read Sacha's article for another approach to getting friendly names for enums. Sacha, thanks again for your feedback.