Proper way to use CollectionViewSource in ViewModel

You have two options to use CollectionViewSource properly with MVVM –

  1. Expose an ObservableCollection of items (Categories in your case) through your ViewModel and create CollectionViewSource in XAML like this –

    <CollectionViewSource Source="{Binding Path=Categories}">
        <CollectionViewSource.SortDescriptions>
           <scm:SortDescription PropertyName="CategoryName" />
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
    

    scm: xmlns:scm="clr-namespace:System.ComponentModel;assembly=Wind‌​owsBase"

    see this – Filtering collections from XAML using CollectionViewSource

  2. Create and Expose an ICollectionView directly from your ViewModel

    see this – How to Navigate, Group, Sort and Filter Data in WPF

Following example shows how to create a collection view and
bind it to a ListBox

View XAML:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    x:Class="CustomerView">
    <ListBox ItemsSource={Binding Customers} />
</Window>

View Codebehind:

public class CustomerView : Window
{
   public CustomerView()
   {
       DataContext = new CustomerViewModel();
   }
}

ViewModel:

public class CustomerViewModel
{
    private readonly ICollectionView customerView;

    public ICollectionView Customers
    {
        get { return customerView; }
    }

    public CustomerViewModel()
    {
        IList<Customer> customers = GetCustomers();
        customerView = CollectionViewSource.GetDefaultView( customers );
    }
}

Update:

Q. If there is no property to sort on? e.g. if there is an ObservableCollection of string or int?

A. In that case you can Simply use . as the property name:

<scm:SortDescription PropertyName="." />

Leave a Comment