How can I create a group footer in a WPF ListView ( GridView )
If your looking for something like this:
(source: bendewey.com)
Then you can use the Template property of the ContainerStyle for the GroupStyle. In this example I use a DockPanel, with the Grid you supplied Docked on the bottom and an ItemsPresenter filling the remainder. In addition in order to get the Items totaled you'd have to use a Converter, which is supplied at the bottom.
Window.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="WpfApplication1.Window3" x:Name="Window" Title="Window3" xmlns:local="clr-namespace:WpfApplication1" Width="640" Height="480"> <Window.Resources> <local:MyDataSource x:Key="MyData" /> <CollectionViewSource x:Key="ViewSource" Source="{Binding Source={StaticResource MyData}, Path=Users}"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="Country" /> </CollectionViewSource.GroupDescriptions> </CollectionViewSource> </Window.Resources> <Grid x:Name="LayoutRoot"> <ListView ItemsSource="{Binding Source={StaticResource ViewSource}}"> <ListView.GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <DockPanel> <Grid DockPanel.Dock="Bottom"> <Grid.Resources> <local:TotalSumConverter x:Key="sumConverter" /> </Grid.Resources> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal"> <TextBlock Grid.Column="0" Text="Total: " FontWeight="Bold"/> <TextBlock Grid.Column="0" Text="{Binding Path=Name}" /> </StackPanel> <Line Grid.Column="1" Stroke="Black" X2="500" Fill="Black" VerticalAlignment="Center" /> <TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Text="{Binding Path=Items, Converter={StaticResource sumConverter}}" /> </Grid> <ItemsPresenter /> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </ListView.GroupStyle> <ListView.View> <GridView> <GridViewColumn Width="140" Header="Name" DisplayMemberBinding="{Binding Name}"/> <GridViewColumn Width="140" Header="Phone Number" DisplayMemberBinding="{Binding Phone}"/> <GridViewColumn Width="140" Header="Country" DisplayMemberBinding="{Binding Country}" /> <GridViewColumn Width="140" Header="Total" DisplayMemberBinding="{Binding Total}" /> </GridView> </ListView.View> </ListView> </Grid></Window>
MyDataSource.cs
public class MyDataSource{ public ObservableCollection<User> Users { get; set; } public MyDataSource() { Users = new ObservableCollection<User>(); LoadDummyData(); } private void LoadDummyData() { Users.Add(new User() { Name = "Frank", Phone = "(122) 555-1234", Country = "USA", Total = 432 }); Users.Add(new User() { Name = "Bob", Phone = "(212) 555-1234", Country = "USA", Total = 456 }); Users.Add(new User() { Name = "Mark", Phone = "(301) 555-1234", Country = "USA", Total = 123 }); Users.Add(new User() { Name = "Pierre", Phone = "+33 (122) 555-1234", Country = "France", Total = 333 }); Users.Add(new User() { Name = "Jacques", Phone = "+33 (122) 555-1234", Country = "France", Total = 222 }); Users.Add(new User() { Name = "Olivier", Phone = "+33 (122) 555-1234", Country = "France", Total = 444 }); }}
User.cs
public class User{ public string Name { get; set; } public string Phone { get; set; } public string Country { get; set; } public double Total { get; set; }}
TotalSumConverter.cs
public class TotalSumConverter : IValueConverter{ public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var users = value as IEnumerable<object>; if (users == null) return "$0.00"; double sum = 0; foreach (var u in users) { sum += ((User)u).Total; } return sum.ToString("c"); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new System.NotImplementedException(); }}