Posted in:

I was recently creating a simple WPF application and was trying to use the MVVM pattern. In this pattern, all the controls on your form are data bound to properties on your “View Model” class. While there are lots of examples of how to do this with Text boxes, List boxes, and even master-detail views, it seems that examples for binding Combo boxes are a little thin on the ground.

What I wanted to do was bind the items in the ComboBox to a list in my ViewModel and to track the currently selected item. I found that there does not seem to be one “official” way of doing this. One approach bound both the ItemsSource and the SelectedValue properties of the Combo box to corresponding properties on ViewModel. The approach I went with uses a CollectionView which is a class included with .NET that encapsulates a list and the concept of a current item as well as supporting the INotifyPropertyChanged interface.

So here is the XAML first. I set the IsSychronizedWithCurrentItem to true to allow us to track the current item on the ItemsSource.

<ComboBox ItemsSource="{Binding Path=Queries}"
          IsSynchronizedWithCurrentItem="True"
          DisplayMemberPath="Name" />

The code in the ViewModel first creates the List, and then creates a CollectionView based on that list. This allows us to set the CurrentItem from the ViewModel as well as get notified whenever the CurrentItem changes.

public MainWindowViewModel()
{
    IList<Query> availableQueries = new List<Query>();
    // fill the list...

    Queries = new CollectionView(availableQueries);
    Queries.MoveCurrentTo(availableQueries[0]);
    Queries.CurrentChanged += new EventHandler(queries_CurrentChanged);
}

public CollectionView Queries { get; private set; }

void queries_CurrentChanged(object sender, EventArgs e)
{
    Query currentQuery = (Query)Queries.CurrentItem;
}

I’m not sure yet whether using CollectionView is a better approach than the alternatives I have seen which bind the SelectedValue or SelectedItem property. I would be interested to hear in the comments if you think either approach has benefits over the other. One consideration is that Silverlight doesn’t seem to support CollectionView at the moment.

Comments

Comment by Michael Schlegel

Even if some month were gone since you published your article it provides exactly what I was looking for. To answer your question: from my point of view your suggestion is almost an imperative if one applies the MVVM pattern on comboboxes. Thanks a lot!

Michael Schlegel
Comment by Anonymous

Hi Mark,

Great posts,

I read your post about MVVM ListBox filtering, what i´m looking for is something in between.

If i for instance have an application with a number of Combo boxes bound with a CollectionView and i want the selected item in one of them to affect a filter in another ComboBox.

How would you go about doing that? I´ve added a filter by just using myCollectionView.Filter = methodname, in the CurrentChanged eventhandler of the CollectionView. It runs the filter method allright but the View wont update even with myCollectionView.Refresh().

Any thoughts on this? Do i need to use a ObeservableCollection instead of CollectionView?

I really liked CollectionView approach so would be nice i could stick to that.

Anonymous
Comment by Mark H

hmm, not sure anonymous, I haven't done much WPF recently. You should ask on StackOverflow

Comment by Anonymous

Thanks for answering atleast :)

Got it working with this approach : http://www.wpftutorial.net/DataViews.html

Very simular to your post..

Anonymous
Comment by Anonymous

Hi Mark,

good idea, but what is to do, when
you want validate with 'DataErrorValidationRule', i.e. you have to set ValidateOnDataError=True' in your XAML?

Felix

Anonymous
Comment by Mark H

@Anonymous, I'd recommend asking that on StackOverflow. I haven't done much with Data Validation in WPF

Comment by Anonymous

Oh my god!! Thank you so much. I love it, worked perfectly and now I can use this method in other areas where I guess I was probably hacking away to get it to work like this... so simple.

Anonymous