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>
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 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>
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 }); } }
public class User { public string Name { get; set; } public string Phone { get; set; } public string Country { get; set; } public double Total { get; set; } }
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(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With