Dot Net For All

Combobox binding in WPF using MVVM

Combobox binding in WPF

In this article I will take you through the various scenarios in which the combobox can be binded to the datasource in MVVM way. Apart from that we will also go through the three properties which the developers are most confused with i.e. SelectedItem, SelectedValue and DisplayMemberPath.

Before reading the article you can know about the MVVM pattern in WPF here.

I have attached my code along with the article.

SelectedItem, SelectedValue, SelectedValuePath and DisplayMemberPath

First of all talking of the three properties

1.  SelectedItem – Selected Item helps to bind the actual value from the DataSource which will be displayed. This is of type object and we can bind any type derived from object type with this property. Since we will be using the MVVM binding for our combo boxes in that case this is the property which we can use to notify VM that item has been selected.

2.  SelectedValue and SelectedValuePath – These are the two most confusing and misinterpreted properties for combobox. But these properties come to rescue when we want to bind our combobox with the value from already created object.  Please check my last scenario in the following list to get a brief idea about the properties.

Here I will use three types of bindings to combobox from the VM. I have

1.  Binding string collection to Combobox – First case we will take is of binding string collection to combobox. I have defined a Standards property of type Ilist<string> in my VM. This property I am binding to my first combobox as shown below.

<ComboBox HorizontalAlignment="Left" Margin="183,39,0,0" VerticalAlignment="Top" Width="120" 
ItemsSource="{Binding Standards}"  SelectedItem="{Binding SelectedStandard}"/>

Since we are using the MVVM approach here in this article, that is why we cannot have SelectionChanged event for my combobox which prevents me to achieve MVVM design. That is why I have SelectedItem property defined, the setter of SelectedStandard is invoked when I change the selection. This selector I can use to achieve any functionality which I would have achieved inSelectionChanged event.

2.       Binding to collection of UserDefined Type – In this case I want to bind a collection of some user defined type which in my case is Place class. I have created a property of type IList<Place> in my VM.  Now I want my class properties to shown something like as shown below.

Now the above scenario can be achieved in number of ways in the combobox which I will take one by one as mentioned below –

<ComboBox HorizontalAlignment="Left" Margin="183,87,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Places}" />

And my VM class for these two properties look as shown below

public IList<Place> Places   
        {  
            get{ return places; }  
            set{ places = value; }  
        }

And the definition of my place class is as shown below

public class Place  
    {  
        public int ID { get; set; }  
        public string Country { get; set; }  
        public string City { get; set; }          
    }

But if I simply bind my collection of Place class from VM to view the output would be something as shown below

Which shown that the combobox simply calls the ToString() method of the class while binding. So to get the desired result we need to override the ToString() in our Place class as shown below

public override string ToString()  
{  
    return City + " - " + Country;  
}

Which in turn would give us the desired result as we wanted. But suppose if our Place class has the overridden implementation of the ToString() function and we do not want to remove it and we only want to display the City in the combobox in that case DisplayMemberPath would come to our rescue as shown in the code below

<ComboBox HorizontalAlignment="Left" Margin="183,80,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Places}"
 SelectedItem="{Binding SelectedPlace}" DisplayMemberPath="City"  />

And the output of this would look as shown below

 <ComboBox HorizontalAlignment="Left" Margin="183,87,0,0" VerticalAlignment="Top" 
Width="120" ItemsSource="{Binding Places}" >
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding City}"></TextBlock>
                        <TextBlock Text="-"></TextBlock>
                        <TextBlock Text="{Binding Country}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
          </ComboBox>

3. Binding Enum to Combobox – We can bind an enum to the combobox by creating an ObjectDataProvider in the resource and binding it to the combobox as shown in the snippet below. I have created an enum Gender and binded it to combobox.

<Window.Resources>  
        <ObjectDataProvider x:Key="genderEnum" MethodName="GetValues"  
                            ObjectType="{x:Type System:Enum}">  
            <ObjectDataProvider.MethodParameters>  
                <x:Type TypeName="local:Gender"/>  
            </ObjectDataProvider.MethodParameters>  
        </ObjectDataProvider>  
    </Window.Resources>

And the combobox code would like as shown below –

<ComboBox ItemsSource="{Binding Source={StaticResource genderEnum}}" 
SelectedItem="{Binding SelectedGender}" HorizontalAlignment="Left" 
Margin="183,175,0,0" VerticalAlignment="Top" Width="120"/>

4. Binding to SelectedValue and SelectedValuePath –

Suppose we already have an object and we want to bind that object to one of our view and that view contains a combobox in that case both of these properties comes to out rescue. There can be scenarios in which the control comes to the current view after some action with a prepoulated object, the earlier cases which I have discussed till now are creating a object for some operation to be done. I have created MainVM object as shown below

this.DataContext = new MainVM() { Name = "Vikram", CityID =2 };

From the above scenario we can see that the MainVM object is created for “Vikram” with CityID as 2. Now if we check the code of the combobox in xaml, we can see it as following

<ComboBox HorizontalAlignment="Left" Margin="183,253,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Places}" SelectedValue="{Binding CityID, Mode=TwoWay}" SelectedValuePath="{Binding SelectedValuePath}" DisplayMemberPath="City"  />

As soon as my view come in the screen it can be seen as following

I hope I have tried well to make the properties of the combobox clear as much as possible. Please leave your suggestions or concerns.

The sample code for the project can be found here

To learn C# and face interview with confidence I have recommended some very good books. These books can really help you to understand .NET and C#. Below is the link:

Best books to Learn csharp(C#) programming

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview