wp7 CollectionViewSource – sorting a listbox

2 minute read

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:

 

collviewsrc

 

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>

<p>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:</p> <blockquote> <p>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;
</p> </blockquote> <p>(Note: I am using the code behind here just for illustrative purposes. I would usually expose the CollectionViewSource from a View Model).</p> <p>and the xaml changes to:</p> <blockquote> <p><ListBox Grid.Row="1" x:Name="ListBox"
                    
Margin="0,0,-12,0"
                    
ItemsSource="{Binding Source.View}">
</p> </blockquote> <p>Now, as a simple example of what we can do I attach two buttons with click handlers to enable sorting of the ListBox. So, </p> <blockquote> <p>           <StackPanel Grid.Row="0"Orientation="Horizontal">
                <
ButtonContent="Asc"Click="AscButtonClick"></Button>
                <
ButtonContent="Desc"
                      
Click="DescButtonClick"></Button>
            </
StackPanel>
</p> </blockquote> <p>with the click handlers defined like this…</p> <blockquote> <p>        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));
        }
</p> 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. </blockquote> <p>The project source can be downloaded here https://skydrive.live.com/?cid=4f1b7368284539e5&sc=documents&id=4F1B7368284539E5%21352</p> Technorati Tags: ,,,,,,,,,,,,,,,,,,,,
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

Comments