Silverlight 3, the CollectionViewSource and sorting

In my previous post we were introduced to the CollectionViewSource. We have multiple ItemSources binding to the same collection using a CollectionViewSource ? very powerful.  Now what if we want to sort the items displayed in one of our grid cells?  We will focus on row one and column one for the rest of this post.

I?ve added some more default data to the Control?s constructor to make things a little more interesting and also notice I have added a few buttons to the bottom of our control:

image

The Sort by Name button adds a sort description to the CollectionViewSource

theDataContext[0].Column1.View.SortDescriptions.Add(new SortDescription("SomeName",ListSortDirection.Ascending));

This code tells the CollectionViewSource to sort the items in it?s view by the SomeName property in ascending order.  Click the button and we see the following:

image

Click the Clear Sort Descriptions button.

The Sort By Value button tells the CollectionViewSource to sort the items in the view by the SomeValue Property in ascending order.

theDataContext[0].Column1.View.SortDescriptions.Add(new SortDescription("SomeValue", ListSortDirection.Ascending));

Click the button to see the following:

image

This time our list is sorted by the SomeValue property.

Where things get interesting is that you can add multiple sort descriptions.  Try clearing the filter, then adding the name and value filter (in that order) and we see the following:

image

The collection is first sorted by name, then by value.

Clear the filter and click the Value, then name button and we see this:

image

The collection is first sorted by SomeValue, then by SomeName.

The order is important!  If you want to add a sort description to the top of the sort order, simply use the Insert method as follows:

theDataContext[0].Column1.View.SortDescriptions.Insert(0,new SortDescription("SomeValue", ListSortDirection.Ascending));

Here is the modified XAML:



Code Snippet



  1. <UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="SilverlightApplication1.MainPage"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5.    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  6.     <UserControl.Resources>
  7.         <Style TargetType="Button">
  8.             <Setter Property="FontSize" Value="9"/>
  9.         </Style>
  10.     </UserControl.Resources>
  11.   <Grid x:Name="LayoutRoot">
  12.         <ScrollViewer VerticalScrollBarVisibility="Auto">
  13.             <StackPanel Orientation="Vertical">
  14.             <data:DataGrid x:Name="TheMainDataGrid"  AutoGenerateColumns="False" ItemsSource="{Binding}" HeadersVisibility="Column">
  15.                 <data:DataGrid.Columns>
  16.                     <data:DataGridTemplateColumn Header="Column 1">
  17.                         <data:DataGridTemplateColumn.CellTemplate>
  18.                             <DataTemplate>
  19.                                 <ListBox MinHeight="15" ItemsSource="{Binding Path=Column1.View}" >
  20.                                     <ListBox.ItemTemplate>
  21.                                         <DataTemplate>
  22.                                             <StackPanel Orientation="Horizontal">
  23.                                                 <TextBlock Margin="10" Text="{Binding Path=SomeName}" />
  24.                                                 <TextBlock Margin="10" Text="{Binding SomeValue}" />
  25.                                             </StackPanel>
  26.                                         </DataTemplate>
  27.                                     </ListBox.ItemTemplate>
  28.                                 </ListBox>
  29.                             </DataTemplate>
  30.                         </data:DataGridTemplateColumn.CellTemplate>
  31.                     </data:DataGridTemplateColumn>
  32.                     <data:DataGridTemplateColumn Header="Column 2">
  33.                         <data:DataGridTemplateColumn.CellTemplate>
  34.                             <DataTemplate>
  35.                                 <ListBox MinHeight="15" ItemsSource="{Binding Path=Column2.View}" >
  36.                                     <ListBox.ItemTemplate>
  37.                                         <DataTemplate>
  38.                                             <StackPanel Orientation="Horizontal">
  39.                                                 <TextBlock Margin="10" Text="{Binding SomeName}" />
  40.                                                 <TextBlock Margin="10" Text="{Binding SomeValue}" />
  41.                                             </StackPanel>
  42.                                         </DataTemplate>
  43.                                     </ListBox.ItemTemplate>
  44.                                 </ListBox>
  45.                             </DataTemplate>
  46.                         </data:DataGridTemplateColumn.CellTemplate>
  47.                     </data:DataGridTemplateColumn>
  48.                 </data:DataGrid.Columns>
  49.             </data:DataGrid>
  50.             <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
  51.                 <TextBlock Margin="5" Text="Name:"/>
  52.                 <TextBox x:Name="tbNAme" Margin="5" Width="100"></TextBox>
  53.                 <TextBlock Margin="5" Width="100" Text="Value:"/>
  54.                 <TextBox x:Name="tbValue" Margin="5" Width="100"></TextBox>
  55.                 <Button x:Name="AddButton" Margin="5" Content="Add" Click="AddButton_Click"/>
  56.             </StackPanel>
  57.             <StackPanel HorizontalAlignment="Left">
  58.                 <Button x:Name="ChangeNameButton" Width="150" Content="Change Name" Click="ChangeNameButton_Click"/>
  59.                 <Button x:Name="ChangeValueButton" Width="150" Content="Change Value" Click="ChangeValueButton_Click"/>
  60.                 <Button x:Name="refresh" Width="150" Content="Refresh CVS" Click="refresh_Click" />
  61.                 <Button x:Name="AddNameSort" Width="150" Content="Sort by Name" Click="AddNameSort_Click"/>
  62.                 <Button x:Name="AddValueSort" Width="150" Content="Sort by Value" Click="AddValueSort_Click"/>
  63.                 <Button x:Name="ClearSort" Width="150" Content="Clear Sort Descriptions" Click="ClearSort_Click"/>
  64.             </StackPanel>
  65.         </StackPanel>
  66.             </ScrollViewer>
  67.   </Grid>
  68. </ UserControl>




Here is the modified code behind:



Code Snippet



  1. using System.Collections.ObjectModel;
  2. using System.Windows.Controls;
  3. using System.Windows.Data;
  4. using System.ComponentModel;
  5. namespace SilverlightApplication1
  6. {
  7.     public partial class MainPage : UserControl
  8.     {
  9.         ObservableCollection<TestClass> theMainCollection ;
  10.         ObservableCollection<TheRowClass> theDataContext;
  11.         public MainPage()
  12.         {
  13.             InitializeComponent();
  14.             theMainCollection = new ObservableCollection<TestClass>()
  15.                 { new TestClass() {SomeName="A",SomeValue=11},
  16.                     new TestClass() {SomeName="A",SomeValue=12},
  17.                     new TestClass() {SomeName="A",SomeValue=10},
  18.                     new TestClass() {SomeName="AB",SomeValue=21},
  19.                     new TestClass() {SomeName="A",SomeValue=13},
  20.                     new TestClass() {SomeName="B",SomeValue=13},
  21.                     new TestClass() {SomeName="B",SomeValue=14},
  22.                     new TestClass() {SomeName="AB",SomeValue=11},
  23.                     new TestClass() {SomeName="BC",SomeValue=22},
  24.                     new TestClass() {SomeName="AB",SomeValue=23},
  25.                     new TestClass() {SomeName="BC",SomeValue=24}
  26.                 };
  27.           
  28.             theDataContext = new ObservableCollection<TheRowClass>();
  29.             theDataContext.Add(new TheRowClass(theMainCollection));
  30.             theDataContext.Add(new TheRowClass(theMainCollection));
  31.             TheMainDataGrid.DataContext = theDataContext;
  32.             AddFilter(theDataContext[0].Column1, 1, 1);
  33.             AddFilter(theDataContext[0].Column2, 1, 2);
  34.             AddFilter(theDataContext[1].Column1, 2, 1);
  35.             AddFilter(theDataContext[1].Column2, 2, 2);
  36.            
  37.         }
  38.         private void AddFilter(CollectionViewSource cvs, int row, int column)
  39.         {
  40.             cvs.Filter += delegate(object o, FilterEventArgs eArgs)
  41.             {
  42.                 //Simple filter saying if column = 1 look for an A in the SomeName property
  43.                 //Else look for a B.  If we are in Row 1 look for a 1 in the SomeValue property
  44.                 //Else look for a 2
  45.                 string columnFilter;
  46.                 if (row == 1)
  47.                     columnFilter = "A";
  48.                 else
  49.                     columnFilter = "B";
  50.                 if ((eArgs.Item as TestClass).SomeValue.ToString().Contains(column.ToString()) && (eArgs.Item as TestClass).SomeName.Contains(columnFilter))
  51.                     eArgs.Accepted = true;
  52.                 else
  53.                     eArgs.Accepted = false;
  54.             };
  55.         }
  56.         private void AddButton_Click(object sender, System.Windows.RoutedEventArgs e)
  57.         {
  58.             TestClass tc = new TestClass();
  59.             tc.SomeName = tbNAme.Text;
  60.             tc.SomeValue = int.Parse(tbValue.Text);
  61.             theMainCollection.Add(tc);
  62.         }
  63.         private void ChangeNameButton_Click(object sender, System.Windows.RoutedEventArgs e)
  64.         {
  65.             theMainCollection[theMainCollection.Count-1].SomeName = "B";
  66.         }
  67.         private void ChangeValueButton_Click(object sender, System.Windows.RoutedEventArgs e)
  68.         {
  69.             theMainCollection[theMainCollection.Count - 1].SomeValue = 25;
  70.         }
  71.         private void refresh_Click(object sender, System.Windows.RoutedEventArgs e)
  72.         {
  73.             theDataContext[0].Column1.View.Refresh();
  74.             theDataContext[1].Column1.View.Refresh();
  75.             theDataContext[0].Column2.View.Refresh();
  76.             theDataContext[1].Column2.View.Refresh();
  77.         }
  78.         private void AddNameSort_Click(object sender, System.Windows.RoutedEventArgs e)
  79.         {
  80.             theDataContext[0].Column1.View.SortDescriptions.Add(new SortDescription("SomeName",ListSortDirection.Ascending));
  81.         }
  82.         private void AddValueSort_Click(object sender, System.Windows.RoutedEventArgs e)
  83.         {
  84.             theDataContext[0].Column1.View.SortDescriptions.Add(new SortDescription("SomeValue", ListSortDirection.Ascending));
  85.         }
  86.         private void ClearSort_Click(object sender, System.Windows.RoutedEventArgs e)
  87.         {
  88.             theDataContext[0].Column1.View.SortDescriptions.Clear();
  89.         }
  90.     }
  91. }




See my previous post to get the supporting code.


Posted by: Tim Star
Posted on: 7/5/2010 at 8:56 PM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Add comment




biuquote
  • Comment
  • Preview
Loading


Contact Us 651-994-8558 1-800-866-9884
Home | Training | Curriculum | Course Finder | Schedule | Enroll | Twin Cities Java User Group | Consulting | Foundation | Jobs | About Us | Our Story | Press Room | Instructors | President | Map & Directions | Sitemap

Java Training | JSF / Struts / Spring / Hibernate Training | Java Power Tools Training | .NET 4.0 & Visual Studio 2010 Training | .NET 3.5 and Visual Studio 2008 Training | .NET 2.0 and Visual Studio 2003 Training | Prism / MVVM / MEF Training | Microsoft Web Development Training | Cloud Computing Training | Ajax / Web Services / XML Training | Groovy and Grails Training | SQL Server 2008 Training | SQL Server 2005 Training | Mobile Development Training | SharePoint 2010 Training | SharePoint 2007 Training | Agile, Process, Analysis & Design Training | Arch/Design Patterns Training | Microsoft Official Curriculum Training | Web Development Training | Ruby Training | Rational Application Developer (RAD) Training | WebSphere Application Server Training | WebSphere Portal Training | WebLogic Training | Boot Camp Training | Project Management Training | C++ Training | Metro / WinRT / Windows 8 Development Training | Retired

Intertech delivers training on-site and virtually serving cities including Phoenix, AZ | San Francisco, CA | Los Angeles, CA | San Diego, CA | San Jose, CA | Washington, DC | Chicago, IL | Orlando, FL | Boston, MA | Duluth, MN | Minneapolis St. Paul, MN | Rochester, MN | Raleigh-Durham, NC | New York, NY | Philadelphia, PA | Austin, TX | Dallas, TX | Houston, TX | Seattle, WA.