In data driven applications, we often need to show a set of records grouped by a specific field. In this article, we’ll see how we can use a WPF ListView to groups data.
Let's start with an example.
Step 1: First we create a class as Employee into MainWindow.xaml.cs
First, let’s create a class Employee and an enum Department. Each employee belongs to a department.
- public class Employee
- {
- public string Name { get; set; }
- public int Age { get; set; }
- public string Email { get; set; }
- public Department dept { get; set; }
- }
- public enum Department
- {
- Accounting,
- Economics,
- Finance,
- Management,
- Marketing,
- }
Step 2: Create Xaml as given below. Add ListView into Grid.
Now, let’s create a UI and bind and display some data to the controls. Once we have data filled, we will apply WPF tricks to customize the appearance even further.
- <Window x:Class="ListViewGrouping.MainWindow"
- 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"
- xmlns:local="clr-namespace:ListViewGrouping"
- mc:Ignorable="d"
- Title="ListViewGrouping" Height="450" Width="800">
- <Grid>
- <ListView Name="lvEmps">
- <ListView.View>
- <GridView>
- <GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
- <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
- <GridViewColumn Header="Email" Width="150" DisplayMemberBinding="{Binding Email}" />
- </GridView> </ListView.View>
- <ListView.GroupStyle>
- <GroupStyle>
- <GroupStyle.HeaderTemplate>
- <DataTemplate>
- <TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Name}"/>
- </DataTemplate>
- </GroupStyle.HeaderTemplate>
- </GroupStyle>
- </ListView.GroupStyle>
- </ListView>
- </Grid>
- </Window>
Step 3: Insert the values into the ListView while initialize the components.
Now, we are going to create some objects. A List<Employee> is a collection of Employee objects. A collection of objects will be then bound to the ListsView control.
- public partial class MainWindow : Window
- {
- public MainWindow()
- {
- InitializeComponent();
- List<Employee> items = new List<Employee>();
- items.Add(new Employee() { Name = "Ram Charan", Age = 33, Email = "[email protected]", dept = Department.Accounting });
- items.Add(new Employee() { Name = "Raju Rastogi", Age = 22, Email = "[email protected]", dept = Department.Management });
- items.Add(new Employee() { Name = "Dilip Bhatt", Age = 35, Email = "[email protected]", dept = Department.Economics });
- items.Add(new Employee() { Name = "Dipesh Patil", Age = 33, Email = "[email protected]", dept = Department.Accounting });
- items.Add(new Employee() { Name = "Ronak Sharma", Age = 39, Email = "[email protected]", dept = Department.Finance });
- items.Add(new Employee() { Name = "Punit Shah", Age = 43, Email = "[email protected]", dept = Department.Economics });
- items.Add(new Employee() { Name = "Haresh Shukla", Age = 25, Email = "[email protected]", dept = Department.Management });
- items.Add(new Employee() { Name = "John Cena", Age = 32, Email = "[email protected]", dept = Department.Accounting });
- items.Add(new Employee() { Name = "Govind Patil", Age = 41, Email = "[email protected]", dept = Department.Marketing });
- lvEmps.ItemsSource = items;
- CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvEmps.ItemsSource);
- PropertyGroupDescription groupDescription = new PropertyGroupDescription("dept");
- view.GroupDescriptions.Add(groupDescription);
- }
- }
Now, let’s build and run the application. The output UI looks like the following:
As above figure, you can see the department wise grouping on the employee detail.
Step 4: Customizing the group header
Now, let’s customize the group header.
- <Window x:Class="ListViewGrouping.MainWindow"
- 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"
- xmlns:local="clr-namespace:ListViewGrouping"
- mc:Ignorable="d"
- Title="ListViewGrouping" Height="450" Width="800">
- <Grid>
- <ListView Name="lvEmps">
- <ListView.View>
- <GridView>
- <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
- <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
- </GridView>
- </ListView.View>
- <ListView.GroupStyle>
- <GroupStyle>
- <GroupStyle.ContainerStyle>
- <Style TargetType="{x:Type GroupItem}">
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate>
- <Expander IsExpanded="True">
- <Expander.Header>
- <StackPanel Orientation="Horizontal">
- <TextBlock Text="{Binding Name}" FontWeight="DemiBold" Foreground="DarkSlateGray" FontSize="20"VerticalAlignment="Bottom" />
- <TextBlock Text="{Binding ItemCount}" FontSize="18" Foreground="Gray" FontWeight="Bold"FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
- <TextBlock Text=" record(s)" FontSize="16" Foreground="Gray" FontStyle="Italic"VerticalAlignment="Bottom" />
- </StackPanel>
- </Expander.Header>
- <ItemsPresenter />
- </Expander>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </GroupStyle.ContainerStyle>
- </GroupStyle>
- </ListView.GroupStyle>
- </ListView>
- </Grid>
- </Window>
After applying the above code, run the project. You can see the grouping output as below figure. Now, you can see there is an Expander control groups records based on their departments.
After closing the Expanders, the UI looks like the following:
In this code sample, we saw how to use a WPF ListView control to group data.