Advertisement

Grouping data in Silverlight DataGrid

UPDATED: If you found this post via a search, the below information was for Silverlight 3 beta and no longer works in Silverlight 3 release.  Click here for an updated tutorial on grouping in the Silverlight DataGrid for Silverlight 3.

I got this question on how do you add grouping to the DataGrid in Silverlight without using the RIA Services ObjectDataSource.  Frankly I didn’t know off the top of my head either and I’ve since learned it isn’t obvious.  Allow me to explain the steps.

In my simple app I have a static class that supplies some hard-coded data:

   1: public List<Person> GetPeople()
   2: {
   3:     List<Person> peeps = new List<Person>();
   4:     peeps.Add(new Person() { FirstName = "Tim", LastName="Heuer", Gender="M", AgeGroup="Adult" });
   5:     peeps.Add(new Person() { FirstName = "Lisa", LastName="Heuer", Gender="F", AgeGroup="Adult" });
   6:     peeps.Add(new Person() { FirstName = "Zoe", LastName = "Heuer", Gender="F", AgeGroup="Kid" });
   7:     peeps.Add(new Person() { FirstName = "Zane", LastName = "Heuer", Gender="M", AgeGroup="Kid" });
   8:     return peeps;
   9: }

You can see there is a Gender field and I want to list them grouped on that in a DataGrid.  So I would first add a reference to the DataGrid control library and add that:

   1: <navigation:Page x:Class="SilverlightApplication32.AboutPage" 
   2:            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   5:            xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
   6:            Title="AboutPage Page">
   7:     <Grid x:Name="LayoutRoot" Background="White">
   8:         <StackPanel>
   9:             <TextBlock Text="Detail" Style="{StaticResource HeaderTextStyle}"/>
  10:             <TextBlock Text="Detail list of members with gender." Style="{StaticResource ContentTextStyle}"/>
  11:             <data:DataGrid ItemsSource="{Binding}"/>
  12:         </StackPanel>
  13:     </Grid>
  14: </navigation:Page>

Notice the xmlns attribute in the control (this is in a navigation page, but the syntax is the same).  Now how to add the grouping?  You’d hope it would be something as simple as GroupPathName on the DataGrid or something.  But remember that grouping can be done multilevel.  So to add grouping we have to do some things first.  First, add a reference to System.ComponentModel in your application.  Then add another xmlns to your control for the library, since that is where the PropertyGroupDescription is located.  The result is that we have:

   1: <navigation:Page x:Class="SilverlightApplication32.AboutPage" 
   2:            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   5:            xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
   6:            xmlns:cm="clr-namespace:System.Windows.Data;assembly=System.ComponentModel"
   7:            Title="AboutPage Page">
   8:     <Grid x:Name="LayoutRoot" Background="White">
   9:         <StackPanel>
  10:             <TextBlock Text="Detail" Style="{StaticResource HeaderTextStyle}"/>
  11:             <TextBlock Text="Detail list of members with gender." Style="{StaticResource ContentTextStyle}"/>
  12:             <data:DataGrid ItemsSource="{Binding}">
  13:                 <data:DataGrid.GroupDescriptions>
  14:                     <cm:PropertyGroupDescription PropertyName="Gender" />
  15:                 </data:DataGrid.GroupDescriptions>
  16:             </data:DataGrid>
  17:         </StackPanel>
  18:     </Grid>
  19: </navigation:Page>

Notice the ComponentModel use within the DataGrid’s GroupDescriptions node.  This would render in a UI like:

DataGrid single grouping

Want to add multilevel grouping? Just add another PropertyGroupDescription:

   1: <data:DataGrid ItemsSource="{Binding}">
   2:     <data:DataGrid.GroupDescriptions>
   3:         <cm:PropertyGroupDescription PropertyName="Gender" />
   4:         <cm:PropertyGroupDescription PropertyName="AgeGroup" />
   5:     </data:DataGrid.GroupDescriptions>
   6: </data:DataGrid>

And it will render top-down:

DataGrid multilevel grouping

You can also do this in code of course like this (assuming the DataGrid is named “MyGrid”:

   1: MyGrid.GroupDescriptions.Add(new PropertyGroupDescription("Gender"));

I found this information on one of our tester’s site, Naga Satish.  Naga also has some other valuable DataGrid information:

I recommend you bookmark a few :-).


This work is licensed under a Creative Commons Attribution By license.

  1. 4/9/2009 6:05 AM | # re: Grouping data in Silverlight DataGrid
    Thank you so much for this tutorial. The information in Naga Satish is missing some details which makes it so hard to follow his steps. and also it's difficult to test his codes. your tutorial is complete, and that's very important.
    Thanks again for the good job.
    Rachida
  2. 4/9/2009 12:41 PM | # re: Grouping data in Silverlight DataGrid
    That looks easy, what if I wanted to sum a number and add it to each group. E.G.
    GroupOne 10
    ----Item 5
    ----Item 3
    ----Item 2
  3. 4/9/2009 2:15 PM | # re: Grouping data in Silverlight DataGrid
    Great.
  4. 4/9/2009 2:18 PM | # re: Grouping data in Silverlight DataGrid
    Great, is this working on Silverlight 2? Thanks.
  5. 4/22/2009 4:23 PM | # re: Grouping data in Silverlight DataGrid
    Tim, I implemented this item in my page however I can not get the rows to collapse on load. Here is my code any help would be appreciated..

    PagedCollectionView collectionView = new PagedCollectionView(e.Result);
    collectionView.GroupDescriptions.Add(new PropertyGroupDescription("FOO"));
    collectionView.GroupDescriptions.Add(new PropertyGroupDescription("Process"));
    collectionView.GroupDescriptions.Add(new PropertyGroupDescription("Area"));
    rawDataGrid.ItemsSource = collectionView;

    foreach (CollectionViewGroup x in collectionView.Groups)
    {
    rawDataGrid.CollapseRowGroup(x, true);
    }
  6. 4/24/2009 9:28 AM | # re: Grouping data in Silverlight DataGrid
    Great feature, but will it be possible to use it when I use indexers to get the property i bind to. That is, i bind to a list of a list, and use a converter to get the parameter (e.g as described here: www.scottlogic.co.uk/.../binding-a-silverlight-... )


  7. 5/5/2009 7:16 AM | # re: Grouping data in Silverlight DataGrid
    Hi, Is this grouping possible in Silverlight 2.0?
  8. 5/8/2009 5:10 AM | # re: Grouping data in Silverlight DataGrid
    Hi Tim

    I tried you example and had partial success....

    I have a page with a Combo box - this is used to select a Customer. Having selected the Customer, the Customer's addresses are displayed in the DataGrid and are grouped by County (or State).

    So, the page loads and my data grid is Collapsed.

    I select Customer X from my ComboBox and their addresses appear in the DataGrid, nicely grouped by County.

    I then select Customer Y from my ComboBox and their addresses appear in the DataGrid, but this time there's no Grouping.

    I then re-select Customer X - again, their addresses appear, but sadly this time not grouped.

    The XAML for the data grid is as follows (I've tried putting the GroupDescriptions after the Column descriptions)

    <data:DataGrid x:Name="AddressList" Grid.Row="1" Visibility="Collapsed" AutoGenerateColumns="False" >
    <data:DataGrid.GroupDescriptions>
    <compmod:PropertyGroupDescription PropertyName="County"/>
    </data:DataGrid.GroupDescriptions>
    <data:DataGrid.Columns>
    <data:DataGridTextColumn Binding="{Binding AddressCode}" Header="Code" />
    <data:DataGridTextColumn Binding="{Binding Street1}" Header="Street 1" />
    <data:DataGridTextColumn Binding="{Binding Street2}" Header="Street 2" />
    <data:DataGridTextColumn Binding="{Binding Town}" Header="Town" />
    <data:DataGridTextColumn Binding="{Binding Postcode}" Header="Postcode" />
    </data:DataGrid.Columns>
    </data:DataGrid>

    And my C# code is simply:

    this.AddressList.ItemsSource = addressList;
    this.AddressList.Visibility = Visibility.Visible;

    (addressList is List<Address>).

    Any ideas?
  9. 6/17/2009 3:05 AM | # re: Grouping data in Silverlight DataGrid
    Hi Tim,
    Thank you for this good tutorial, but still have some questsions:

    - Is it possible to change the generated Text for the group header (Gener: M (2 items)

    - Is it possible to collapse/expand groups programatically?
  10. 6/29/2009 8:01 AM | # re: Grouping data in Silverlight DataGrid
    Hi, Griff,

    Just let you know i had the same problem, this is what i do:

    myDataGrid.ItemsSource = alist;
    if(myDataGrid.GroupDescriptions.Count == 0)
    myDataGrid.GroupDescriptions.Add(new PropertyGroupDescription("County"));

    obviously this is a bug in SL3 beta, it is beta anyway.


  11. 7/14/2009 5:16 PM | # re: Grouping data in Silverlight DataGrid
    Tim, Can you update this for SL3 RTW? There appears to be no System.ComponentModel available in SL3 RTW (even with July Toolkit installed), and thus no GroupDescriptions.
  12. 7/14/2009 5:40 PM | # re: Grouping data in Silverlight DataGrid
    For those who need answers before Tim updates this post, see here:
    msdn.microsoft.com/.../cc645049%28VS.95%29.aspx
    and here:
    msdn.microsoft.com/.../dd833072%28VS.95%29.aspx

    Short answer: You can't do this in XAML anymore. You have to do it in code.
  13. 8/3/2009 6:29 AM | # re: Grouping data in Silverlight DataGrid
    hi~ man ,i got big problem, see this:
    <datagrid>
    <clounms />

    <datagrid>
    </datagrid>

    </datagrid>
    so,how put values in sub_datagrid? 3Q~!
    myoil.oem@gmail.com
  14. 8/3/2009 7:08 AM | # re: Grouping data in Silverlight DataGrid
    sorry,mail,my.oiloem@gmail.com
  15. 8/17/2009 10:23 PM | # re: Grouping data in Silverlight DataGrid
    Thank you CoderX for letting us know that this can't be done anymore. I have been trying to find some explanation of how to do perform the grouping in code through the use of the domain data context but so far I haven't found anything. If anyone knows of any pointers, please share.
  16. 11/11/2009 10:53 PM | # re: Grouping data in Silverlight DataGrid
    HI Griff

    Thanks for tutorial. Its help me a lot. But this is giving me partial solution. I am editing PagedCollectionView template but for specific grope I need different layout. On the basics on group type I need to change layout

    See

    <StackPanel Grid.Column="3" Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,1,0,1">
    <Grid x:Name="gridBin">
    <Rectangle Fill="White" Width="Auto" Margin="0,1,0,1" Stroke="Black"/>
    <TextBlock Text="BIN" Margin="4,0,4,0" Grid.Column="0" Grid.Row="0"/>
    </Grid>
    <Grid x:Name="gridValue">
    <Rectangle Fill="Black" Width="Auto" Margin="0,1,0,1"/>
    <TextBlock Text="{Binding Name}" Margin="4,0,4,0" Foreground="White" />
    </Grid>
    <TextBlock x:Name="ItemCountElement" Margin="4,0,0,0" Visibility="{TemplateBinding ItemCountVisibility}"/>
    <TextBlock Text="Max Bags:"/>
    </StackPanel>

    I need to change property of textBlock and rectangle on the base of grouping value. If U have any sudition plese reply me
  17. 11/17/2009 8:45 PM | # re: Grouping data in Silverlight DataGrid
    @armin: "How do I change the group display name?"

    1. Add a reference to the assembly: System.ComponentModel.DataAnnotations.
    2. Add the namespace System.ComponentModel.DataAnnotations to your class.
    3. Decorate the property defintion your are grouping by with this:
    [Display(Name = "TextThatWillBeDisplayedForGroup")]

    Hope that helps somebody, I stumbled here looking for the answer.

 
Please add 7 and 8 and type the answer here:
First time here? You are looking at the most recent posts. You may also want to check out older archives. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS or email. Thank you for visiting! (hide this)