Click here to Skip to main content
15,888,610 members
Articles / MVVM

Binding to a ComboBox in Silverlight: A Gotcha

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
13 Feb 2011CPOL3 min read 36.3K   4   7
Binding to a ComboBox in Silverlight: A Gotcha

I am often asked what my favorite feature of Silverlight is, and my answer in always “binding”. The binding in Silverlight and WPF was finally done right and it is an incredibly powerful tool. However, you still run into a few “gotchas” every once in a while and one happened to me the other day with the Combobox. If binding to a Combobox is nothing new to you, then you can skip past the Binding to a Combobox section to the description and setup of the issue.

Binding to a Combobox

Before we can get to the “gotcha” I came across, we first need to set up how to use binding with a Combobox. For my example, we will be using a simplistic MVVM architecture because it helps to demonstrate the point a bit better. Just as a reminder, you don’t have to use binding with the Combobox or to recreate the issue described in this post.

So let’s get started with our view model. For our purposes, the view can be rather simplistic, needing only 2 properties. I added a method to populate our list data just for completion.

C#
public class MainPageViewModel : INotifyPropertyChanged
{
    private string _favoriteConf;
    
    public MainPageViewModel()
    {
        PopulateConfs();
    }
    
    public string FavoriteConf
    {
        get { return _favoriteConf; }
        set
        {
            _favoriteConf = value;
            NotifyPropertyChanged("FavoriteConf");
        }
    }
    
    private List<string> _confs;
    
    public List<string> Confs
    {
        get { return _confs;  }
        set
        {
            _confs = value;
            NotifyPropertyChanged("Confs");
        }
    }
    private void PopulateConfs()
    {
        Confs = new List<string>()
            {"MIX", "TechEd", "PDC", "DevConnections"};
    }
    
    #region INotifyPropertyChanged Members
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected  void NotifyPropertyChanged(string propertyName)
    {
        if(PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

As you can see, we have just the two properties: FavoriteConf and Confs. Our constructor calls the PopulateConfs to add some data for us to work with. (Yes, Conf = Conference, I just didn’t want to write out Conference too many times. :) ).

Now that we have our view model, the next step would be to create our XAML. For this demonstration, we are going to show two elements: a Combobox and a TextBox. The Combobox will have our list of conferences (bound to the Confs property) and the TextBox will show the selected conference by binding to the FavoriteConf property.

If you look at the Combobox, you will notice two different binding statements. The first one is the ItemsSource is bound to the Confs property. This is done with the default OneWay binding, since our Combobox will never be modifying the list of data. The second is the SelectedValue which is bound to the FavoriteConf property. Since we want to update the FavoriteConf value in our view mode when the user selects a drop down, then we do a two-way binding.

Here is our XAML:

XML
<UserControl x:Class="ComboBoxBinding.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ComboBoxBinding"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <local:MainPageViewModel x:Key="viewModel"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White"
          DataContext="{StaticResource viewModel}">
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center"
              Background="LightGray"
              Height="Auto" Width="Auto">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="150"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="25"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock HorizontalAlignment="Center"
                       Text="Select Favorite Conference"/>
            <TextBlock Text="Choose One :" Grid.Row="1"/>
            <ComboBox Grid.Row="1" Grid.Column="1"
                      SelectedValue="{Binding FavoriteConf, Mode=TwoWay}"
                      ItemsSource="{Binding Confs}"/>
            <TextBlock Text="You Picked :" Grid.Row="2"/>
            <TextBox Text="{Binding FavoriteConf}" Grid.Row="2"
                     Grid.Column="1"/>
        </Grid>
    </Grid>
</UserControl>

Note: Since this is a demonstration, I’m creating a static copy of our view model in the resources of our XAML and binding the LayoutRoot’s DataContext to this resource.

If you run the project, the application should look something like this:

image

When you select an item from the Combobox, the TextBox will update with the selected value of the Combobox.

image

Great! It works, everything is added as it should be, right?

Note: Silverlight 4 added some additional properties to the Combobox to make binding easier. You can read a walkthrough of using them on John Papa’s blog here.

Ordering of XAML Properties: The Gotcha

So let’s take our example one step further, but setting a default value for our FavoriteConf value. To do this, we are going to change up our constructor to our view model by adding another line of code:

C#
public MainPageViewModel()
{
    PopulateConfs();
    FavoriteConf = "MIX";
}

If we run our example again, this is what we get:

image

Not exactly what I was looking for. The TextBox picked up the default value of the FavoriteConf, but why didn’t the Combobox? Well it turns out, after much head scratching, that the answer is in our XAML.

Let’s take a look at the XAML of our Combobox again:

XML
<ComboBox Grid.Row="1" Grid.Column="1"
                      SelectedValue="{Binding FavoriteConf, Mode=TwoWay}"
                      ItemsSource="{Binding Confs}"/>

Do you see where we went wrong?

It looked right to me for a while. However, it turns out that ordering of the properties in XAML can affect the behavior of the control. If we switch the order of the ItemsSource and the SelectedValue, your XAML will now look something like this:

XML
<ComboBox Grid.Row="1" Grid.Column="1"
         ItemsSource="{Binding Confs}"
         SelectedValue="{Binding FavoriteConf, Mode=TwoWay}"/>

Now, if we run the two examples side-by-side, we get the following:

image

It turns out that ordering in your XAML can be important and something to look out for if you are not getting the results that you are looking for. If you have found yourself in a similar situation, hopefully this post will help.

You can download the code for this example here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
President Champion DS
United States United States
Tony Champion is a software architect with over 16 years of experience developing with Microsoft technologies. As the president of Champion DS and its lead software architect, he remains active in the latest trends and technologies, creating custom solutions on Microsoft platforms. Tony is an active participant in the community as a Microsoft MVP, international speaker, published author, and blogger. He focuses on a wide range of technologies from web solutions such as HTML5, JavaScript, Silverlight to client platforms for Windows Phone and Windows 8. He can be found on his blog at tonychampion.net and on twitter at @tonychampion.

Comments and Discussions

 
QuestionHow can I bind to a silverlight combobox using Silverlight ComToolkit.Data Pin
Lyle1231322-Aug-14 4:14
Lyle1231322-Aug-14 4:14 
QuestionRegarding combobox Pin
anusha_sipl24-Dec-12 21:12
anusha_sipl24-Dec-12 21:12 
AnswerRe: Regarding combobox Pin
anusha_sipl29-Jan-13 18:38
anusha_sipl29-Jan-13 18:38 
Questiongood.. Pin
bensonissac24-Sep-12 2:51
bensonissac24-Sep-12 2:51 
GeneralMy vote of 5 Pin
Paul McKillop22-Feb-11 5:10
professionalPaul McKillop22-Feb-11 5:10 
GeneralMy vote of 5 Pin
SledgeHammer0117-Feb-11 19:54
SledgeHammer0117-Feb-11 19:54 
Generalgood article [modified] Pin
vikas amin15-Feb-11 9:19
vikas amin15-Feb-11 9:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.