A nice and flexible way to introduce filtering and sorting on a view model data collection is to use a CollectionViewSource. Here’s a quick example:
Starting with a bound collection property like this…
public ObservableCollection<Item> Items { get; set; }
// Constructor
public MainPage()
{
Items = new ObservableCollection<Item>
{
new Item { Date = DateTime.Now.AddDays(-4), Name = "Item 1"},
new Item { Date = DateTime.Now.AddDays(-3), Name = "Item 2"},
new Item { Date = DateTime.Now.AddDays(-5), Name = "Item 3"},
new Item { Date = DateTime.Now.AddDays(-8), Name = "Item 4"},
new Item { Date = DateTime.Now.AddDays(-1), Name = "Item 5"},
};InitializeComponent();
DataContext = this;
}Which is bound to a ListBox like the following:
<ListBox x:Name="ListBox"
Margin="0,0,-12,0"
ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding Date}"
TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}" />
<TextBlock Text="{Binding Name}"
TextWrapping="Wrap"
Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
We simply need to insert a CollectionViewSource object into the data binding chain. To do this we can instantiate a CollectionViewSource, set the Items collection to it’s Source property and bind to the CollectionViewSource’s View property. See below:
public System.Windows.Data.CollectionViewSource Source { get; set; }
// Constructor
public MainPage()
{
Items = new ObservableCollection<Item>
{
new Item { Date = DateTime.Now.AddDays(-4), Text = "Item 1"},
new Item { Date = DateTime.Now.AddDays(-3), Text = "Item 2"},
new Item { Date = DateTime.Now.AddDays(-5), Text = "Item 3"},
new Item { Date = DateTime.Now.AddDays(-8), Text = "Item 4"},
new Item { Date = DateTime.Now.AddDays(-1), Text = "Item 5"},
};Source = new System.Windows.Data.CollectionViewSource();
Source.Source = Items;
(Note: I am using the code behind here just for illustrative purposes. I would usually expose the CollectionViewSource from a View Model).
and the xaml changes to:
<ListBox Grid.Row="1" x:Name="ListBox"
Margin="0,0,-12,0"
ItemsSource="{Binding Source.View}">
Now, as a simple example of what we can do I attach two buttons with click handlers to enable sorting of the ListBox. So,
<StackPanel Grid.Row="0"Orientation="Horizontal">
<ButtonContent="Asc"Click="AscButtonClick"></Button>
<ButtonContent="Desc"
Click="DescButtonClick"></Button>
</StackPanel>
with the click handlers defined like this…
private void DescButtonClick(object sender, RoutedEventArgs e)
{
Source.SortDescriptions.Clear();
Source.SortDescriptions.Add(new SortDescription("Date", ListSortDirection.Descending));
}private void AscButtonClick(object sender, RoutedEventArgs e)
{
Source.SortDescriptions.Clear();
Source.SortDescriptions.Add(new SortDescription("Date", ListSortDirection.Ascending));
}So, what has this achieved? A simple sort of the Listbox, but also since I don’t need to sort my original list a ui-agnostic way to maintain the original data.
The project source can be downloaded here https://skydrive.live.com/?cid=4f1b7368284539e5&sc=documents&id=4F1B7368284539E5%21352
Technorati Tags: CollectionViewSource,ObservableCollection,DataContext,ListBox,ItemsSource,Source,View,Note,code,Model,Grid,Horizontal,Button,Content,Click,Desc,SortDescriptions,Clear,SortDescription,ListSortDirection,purposes
Windows Live Tags: CollectionViewSource,ObservableCollection,DataContext,ListBox,ItemsSource,Source,View,Note,code,Model,Grid,Horizontal,Button,Content,Click,Desc,SortDescriptions,Clear,SortDescription,ListSortDirection,purposes
WordPress Tags: CollectionViewSource,ObservableCollection,DataContext,ListBox,ItemsSource,Source,View,Note,code,Model,Grid,Horizontal,Button,Content,Click,Desc,SortDescriptions,Clear,SortDescription,ListSortDirection,purposes
Thanks Baba, Your code help me a lot.
Nicely explained…..
Thank You very much, you have saved me a lot of time!
Thank you so much 🙂 Thought handle an ObservableCollection would be really complicated until i found your blog! Great!
Very Nice! Thank you very very much!!