How to group records in a WPF ListView control?

How to group records in a WPF ListView control?


Many time we need to show a set of records grouped by a specific field. If you are building Windows app using WPF control, it is very simple to implement using the List View control that we already discussed in the last blog post.

 

Today we are going to discuss how easy it is to add support for grouping in the list. Continue to know about it and implement the same with a simple example.

 

How to group records in a WPF ListView control (www.kunal-chowdhury.com)

 

Hope you already read the previous article on 'Overview to WPF ListView control'. If not, I would recommend you to first read it before starting with this article, as the demo that we are going to create here will refer the previous demo code that we have already created in earlier post.

 

Once you have created your ListView control and binded your data properly to show the records in a tabular format, it's time for us to group them by a column field.

 

To do this, first we need to find the instance of the default view of the 'ListView' control, which you can get by calling the '(CollectionView)CollectionViewSource.GetDefaultView(Employees)', where 'Employees' is the collection of employees which is set as the ItemsSource of the list view control.

 

Next, we need to add a GroupDescription to it. The PropertyGroupDescription that we are going to add here will be one of the column name (e.g. 'Role' in our demo). Here's the code for your reference:

 

var view = (CollectionView)CollectionViewSource.GetDefaultView(Employees);
view.GroupDescriptions.Add(new PropertyGroupDescription("Role"));

 

To group the items in a ListView control, now we need to edit the 'GroupStyle' template of the control. As per our need, we can add any group panel; but for this demo, we will be using the 'Expander' control for easy to understand.

 

To start using this, create a ControlTemplate in your XAML page under the Resources. Now add an Expander and set it's header and child elements template. Here's the XAML code template that we are going to use:

 

<ControlTemplate x:Key="GroupItemTemplate">
    <Expander IsExpanded="False" VerticalAlignment="Bottom" VerticalContentAlignment="Bottom">
        <!-- Header Panel of the Expander control -->
        <Expander.Header>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Converter={StaticResource 
CollectionViewGroupToFieldConverter}}"
FontWeight="Bold" Foreground="Gray" FontSize="20"/> <TextBlock Text="{Binding ItemCount}" Foreground="Green" FontWeight="Bold" FontStyle="Italic" FontSize="20" Margin="4,0,0,0"/> <TextBlock Text=" employee(s)" Foreground="Silver" FontStyle="Italic" FontSize="20"/> </StackPanel> </Expander.Header> <!-- Items panel to hold items inside the Expander control --> <ItemsPresenter /> </Expander> </ControlTemplate>

 

We will be using a converter here to properly display the 'Role' of the employee as the expander header (as we have already mentioned it above). This is require here as the group descriptor will return a property value which we can't directly bind.

 

Here's the convert method implementation of our converter, which you can refer in detail from the solution/project hosted in GitHub (link available at the end of this post):

 

var collectionViewGroup = value as CollectionViewGroup;
var employee = collectionViewGroup.Items[0] as Employee;

return employee.Role;

 

Now the control template that we created earlier, should be linked to the Template property of the ListView GroupStyle. Here's the code for your reference:

 

<ListView.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template" Value="{StaticResource GroupItemTemplate}"/>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</ListView.GroupStyle>

 

That's all about the core code that we need. Now once you run the code (assuming you did the other changes and compile the code successfully), you will see the application running with a ListView grouped by the column that we have specified (in our example, it's 'Role'). Expand the header to see the records listed. Here's the screenshot of our demo application:

 

Group in a WPF ListView control (www.kunal-chowdhury.com)

 

Grouped records in a WPF ListView control (www.kunal-chowdhury.com)

 

So as of now, we learnt the basic of ListView control of WPF. We have also learnt how to group the items with an Expander control. In the next post, we will learn 'How to sort the records in a ListView by a column name'. Till that time, stay tuned to my blog.

 

If you have further questions, do let me know and I will try to revert you as soon as possible; but please bear with me if I delay in response as I will be busy with my other daily work. Just like the previous post, the source code is available under GitHub which you can download from the below link. Cheers!!!

 

 



If you have come this far, it means that you liked what you are reading. Why not reach little more and connect with me directly on Twitter, Facebook, Google+ and LinkedIn. I would love to hear your thoughts and opinions on my articles directly. Also, don't forget to share your views and/or feedback in the comment section below.

0 comments

 
© 2008-2017 Kunal-Chowdhury.com - Microsoft Technology Blog for developers and consumers | Designed by Kunal Chowdhury
Back to top