Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a group footer in a WPF ListView ( GridView )

I have a ListView that displays sales orders, and groups them by status. In WinForms I had a footer at the bottom of each group that displayed the Total sale price for each group, and I would like to do the same in WPF.

I have figured out how to group the orders, but I can't figure out how to create a footer.

This is my current group style:

<ListView.GroupStyle>             <GroupStyle HidesIfEmpty="True">                 <GroupStyle.HeaderTemplate>                     <DataTemplate>                         <!--CollectionViewGroup.Name will be assigned the value of Status for that group.-->                         <!--http://stackoverflow.com/questions/639809/how-do-i-group-items-in-a-wpf-listview-->                         <Grid>                             <Grid.ColumnDefinitions>                                 <ColumnDefinition Width="*" />                                 <ColumnDefinition Width="*" />                             </Grid.ColumnDefinitions>                             <TextBlock Grid.Column="0" Text="{Binding Path=Name}" HorizontalAlignment="Left" FontWeight="Bold"  Foreground="Black"/>                             <Line Grid.Column="1" Stroke="Black" X2="500" Fill="Black" VerticalAlignment="Center" />                         </Grid>                     </DataTemplate>                 </GroupStyle.HeaderTemplate>             </GroupStyle>         </ListView.GroupStyle> 
like image 271
Russ Avatar asked Mar 24 '09 18:03

Russ


1 Answers

If your looking for something like this:

WPF Grouping with Total Sums
(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();     } } 
like image 121
bendewey Avatar answered Sep 22 '22 20:09

bendewey