My previous articles introduced “CollectionViewSource” in Silverlight 4.0. You can check them out here .
To make this article simple, I managed to create a simple Silverlight 4.0 application which consumes a WCF RIA Service created using the WCF RIA Service Library. If you are not familiar with developing applications using the WCF RIA Service Library and Silverlight 4.0, check out a beginner’s article .
The solution was developed using Microsoft Visual Studio 2010 Ultimate Edition with Microsoft Silverlight 4.0 on Windows 7 Ultimate edition. I didn’t really test it in any other environment. I request that you post in the discussion area if you have any problems with execution.
Grouping data using CollectionViewSource in Silverlight with the Declarative Method
Displaying groups of data is necessary in most scenarios. “CollectionViewSource” gives us the ability to group data logically.
Let us consider the following:
< UserControl x : Class ="SLBusinessAppWithRiaLib.CvsGrouping"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns : x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns : d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns : mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc : Ignorable ="d"
d : DesignHeight ="300" d : DesignWidth ="400"
xmlns : sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width ="500" Height ="500">
< UserControl.Resources >
< CollectionViewSource x : Key ="cvsEmp">
< CollectionViewSource.GroupDescriptions >
< PropertyGroupDescription PropertyName ="deptno"/>
</ CollectionViewSource.GroupDescriptions >
</ CollectionViewSource >
</ UserControl.Resources >
< Grid x : Name ="LayoutRoot" Background ="White">
< Grid.RowDefinitions >
< RowDefinition Height ="*" />
</ Grid.RowDefinitions >
< sdk : DataGrid
x : Name ="dgEmp"
Margin ="8" MinHeight ="200" IsReadOnly ="True" />
</ Grid >
</ UserControl >
The main piece of code on which to concentrate from above is the following:
< CollectionViewSource x : Key ="cvsEmp">
< CollectionViewSource.GroupDescriptions >
< PropertyGroupDescription PropertyName ="deptno"/>
</ CollectionViewSource.GroupDescriptions >
</ CollectionViewSource >
We are declaring a “CollectionViewSource” and adding a “GroupDescription.” The “GroupDescription” is assigned a property, “Deptno.” That means “CollectionViewSource” automatically applies grouping based on the “Deptno” property.
The “CollectionViewSource” is populated in code-behind as follows:
Partial Public Class CvsGrouping
Inherits UserControl
Private oCtxt As New BusinessLib.Web. EmpMgrDomainSvc
Private oCvsEmp As CollectionViewSource
Public Sub New()
InitializeComponent()
oCvsEmp = CType(Me.Resources( "cvsEmp" ), CollectionViewSource )
oCvsEmp.Source = oCtxt.emps
oCtxt.Load(oCtxt.GetEmpsQuery())
Me.dgEmp.ItemsSource = oCvsEmp.View
End Sub
End Class
When the above is executed, the output looks similar to the following:
Grouping data using CollectionViewSource in Silverlight with the code-behind method
In the previous section, we saw how to group data in “CollectionViewSource” using the declarative model. In this section, we try to achieve the same result using the code-behind method. We will also examine a multi-column grouping.
To work with this screen, I used the Northwind entity model. The following is the code for the screen's layout.
< UserControl x : Class ="SLBusinessAppWithRiaLib.CvsGroupingCodeBehind"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns : x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns : d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns : mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc : Ignorable ="d"
d : DesignHeight ="300" d : DesignWidth ="400"
xmlns : sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width ="500" Height ="500">
< UserControl.Resources >
< CollectionViewSource x : Key ="cvsNW"/>
</ UserControl.Resources >
< Grid x : Name ="LayoutRoot" Background ="White">
< Grid.RowDefinitions >
< RowDefinition Height ="Auto" />
< RowDefinition Height ="*" />
</ Grid.RowDefinitions >
< StackPanel Orientation ="Horizontal">
< Button x : Name ="btnByCustomer" Content ="By Customer" Margin ="8" />
< Button x : Name ="btnByEmployee" Content ="By Employee" Margin ="8" />
< Button x : Name ="btnByEmpCustomer" Content ="By Employee, then by Customer" Margin ="8" />
</ StackPanel >
< sdk : DataGrid
x : Name ="dgNW"
Grid.Row ="1"
Margin ="8" MinHeight ="200" IsReadOnly ="True" AutoGenerateColumns ="False" >
< sdk : DataGrid.Columns >
< sdk : DataGridTextColumn Header ="OrderID" Binding ="{ Binding OrderID }"/>
< sdk : DataGridTextColumn Header ="CustomerID" Binding ="{ Binding CustomerID }"/>
< sdk : DataGridTextColumn Header ="EmployeeID" Binding ="{ Binding EmployeeID }"/>
< sdk : DataGridTextColumn Header ="Freight" Binding ="{ Binding Freight }"/>
</ sdk : DataGrid.Columns >
</ sdk : DataGrid >
</ Grid >
</ UserControl >
The screen layout for the above code would look like the following screen shot:
Code-behind method continued
This section is a continuation of the previous section. DataGrid in the above code would display four columns from the “Order” table. Now, I would like to group orders based on Customer. The following is the code:
Private Sub btnByCustomer_Click(ByVal sender As System. Object , ByVal e As System.Windows. RoutedEventArgs ) Handles btnByCustomer.Click
oCvsNW.GroupDescriptions.Clear()
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "CustomerID" ))
End Sub
The above would deliver the screen shot shown below as the result:
To group based on Employee, we can change the code as shown below:
Private Sub btnByEmployee_Click(ByVal sender As System. Object , ByVal e As System.Windows. RoutedEventArgs ) Handles btnByEmployee.Click
oCvsNW.GroupDescriptions.Clear()
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "EmployeeID" ))
End Sub
The above code would deliver the following result:
We can also group based on multiple columns, as shown below:
Private Sub btnByEmpCustomer_Click(ByVal sender As System. Object , ByVal e As System.Windows. RoutedEventArgs ) Handles btnByEmpCustomer.Click
oCvsNW.GroupDescriptions.Clear()
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "EmployeeID" ))
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "CustomerID" ))
End Sub
The above code would deliver the following result:
Sorting data using CollectionViewSource in Silverlight with the declarative method
In previous sections, we saw how to group data using “CollectionViewSource.” In this section, we will see how to sort data. Let us consider the following code:
< UserControl x : Class ="SLBusinessAppWithRiaLib.CvsGroupingAndSorting"
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=System.Windows"
xmlns : d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns : mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc : Ignorable ="d"
d : DesignHeight ="300" d : DesignWidth ="400"
xmlns : sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width ="500" Height ="500">
< UserControl.Resources >
<CollectionViewSource x : Key ="cvsEmp">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName ="ename" Direction ="Ascending"></scm:SortDescription>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ UserControl.Resources >
< Grid x : Name ="LayoutRoot" Background ="White">
< Grid.RowDefinitions >
< RowDefinition Height ="*" />
</ Grid.RowDefinitions >
< sdk : DataGrid
x : Name ="dgEmp"
Margin ="8" MinHeight ="200" IsReadOnly ="True" />
</ Grid >
</ UserControl >
In the code above, we wanted to sort the collection based on the “ename” column. That would deliver the result shown below:
Grouping and sorting data using CollectionViewSource in Silverlight with the declarative method
In previous sections, we saw how to group and sort data individually. In this section we will see how to combine both of the operations. Let us consider the following:
< UserControl x : Class ="SLBusinessAppWithRiaLib.CvsGroupingAndSorting"
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=System.Windows"
xmlns : d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns : mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc : Ignorable ="d"
d : DesignHeight ="300" d : DesignWidth ="400"
xmlns : sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width ="500" Height ="500">
< UserControl.Resources >
< CollectionViewSource x : Key ="cvsEmp">
< CollectionViewSource.GroupDescriptions >
< PropertyGroupDescription PropertyName ="deptno"/>
</ CollectionViewSource.GroupDescriptions >
< CollectionViewSource.SortDescriptions >
< scm : SortDescription PropertyName ="deptno" Direction ="Ascending"></ scm : SortDescription >
</ CollectionViewSource.SortDescriptions >
</ CollectionViewSource >
</ UserControl.Resources >
< Grid x : Name ="LayoutRoot" Background ="White">
< Grid.RowDefinitions >
< RowDefinition Height ="*" />
</ Grid.RowDefinitions >
< sdk : DataGrid
x : Name ="dgEmp"
Margin ="8" MinHeight ="200" IsReadOnly ="True" />
</ Grid >
</ UserControl >
The above code would deliver the following result:
We can also sort multiple columns, as shown below:
<CollectionViewSource x : Key ="cvsEmp">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName ="deptno"/>
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName ="deptno" Direction ="Ascending"></scm:SortDescription>
<scm:SortDescription PropertyName ="sal" Direction ="Ascending"></scm:SortDescription>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
The above code would deliver the following result:
Grouping and Sorting data using CollectionViewSource in Silverlight with the code behind method
The following is the screen design:
< UserControl x : Class ="SLBusinessAppWithRiaLib.CvsGroupingAndSortingCodeBehind"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns : x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns : d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns : mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc : Ignorable ="d"
d : DesignHeight ="300" d : DesignWidth ="400"
xmlns : sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width ="500" Height ="500">
< UserControl.Resources >
< CollectionViewSource x : Key ="cvsNW"/>
</ UserControl.Resources >
< Grid x : Name ="LayoutRoot" Background ="White">
< Grid.RowDefinitions >
< RowDefinition Height ="Auto" />
< RowDefinition Height ="*" />
</ Grid.RowDefinitions >
< StackPanel Orientation ="Horizontal">
< Button x : Name ="btnByCustomer" Content ="By Customer" Margin ="8" />
< Button x : Name ="btnByEmployee" Content ="By Employee" Margin ="8" />
< Button x : Name ="btnByEmpCustomer" Content ="By Employee, then by Customer" Margin ="8" />
</ StackPanel >
< sdk : DataGrid
x : Name ="dgNW"
Grid.Row ="1"
Margin ="8" MinHeight ="200" IsReadOnly ="True" AutoGenerateColumns ="False" >
< sdk : DataGrid.Columns >
< sdk : DataGridTextColumn Header ="OrderID" Binding ="{ Binding OrderID }"/>
< sdk : DataGridTextColumn Header ="CustomerID" Binding ="{ Binding CustomerID }"/>
< sdk : DataGridTextColumn Header ="EmployeeID" Binding ="{ Binding EmployeeID }"/>
< sdk : DataGridTextColumn Header ="Freight" Binding ="{ Binding Freight }"/>
</ sdk : DataGrid.Columns >
</ sdk : DataGrid >
</ Grid >
</ UserControl >
The following is the code-behind:
Private Sub btnByCustomer_Click(ByVal sender As System. Object , ByVal e As System.Windows. RoutedEventArgs ) Handles btnByCustomer.Click
oCvsNW.GroupDescriptions.Clear()
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "CustomerID" ))
oCvsNW.SortDescriptions.Clear()
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "CustomerID" , ComponentModel. ListSortDirection .Ascending))
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "Freight" , ComponentModel. ListSortDirection .Ascending))
End Sub
Private Sub btnByEmployee_Click(ByVal sender As System. Object , ByVal e As System.Windows. RoutedEventArgs ) Handles btnByEmployee.Click
oCvsNW.GroupDescriptions.Clear()
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "EmployeeID" ))
oCvsNW.SortDescriptions.Clear()
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "EmployeeID" , ComponentModel. ListSortDirection .Ascending))
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "Freight" , ComponentModel. ListSortDirection .Ascending))
End Sub
Private Sub btnByEmpCustomer_Click(ByVal sender As System. Object , ByVal e As System.Windows. RoutedEventArgs ) Handles btnByEmpCustomer.Click
oCvsNW.GroupDescriptions.Clear()
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "EmployeeID" ))
oCvsNW.GroupDescriptions.Add(New PropertyGroupDescription ( "CustomerID" ))
oCvsNW.SortDescriptions.Clear()
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "EmployeeID" , ComponentModel. ListSortDirection .Ascending))
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "CustomerID" , ComponentModel. ListSortDirection .Ascending))
oCvsNW.SortDescriptions.Add(New System.ComponentModel. SortDescription ( "Freight" , ComponentModel. ListSortDirection .Ascending))
End Sub
In all of the above code, we can observe that we are adding different grouping parameters to the “GroupDescriptions” collection of “CollectionViewSource.” Similarly, we are also adding different sorting parameters to the “SortDescriptions” collection.
Before we apply any new GroupDescriptions or SortDescriptions to existing collections, we need to clear the existing objects in those collections.
My next article will focus on more features of the “CollectionViewSource” element. I hope you enjoyed the article; any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com
Please enable JavaScript to view the comments powered by Disqus. blog comments powered by