Display sum of grouped items in ListView
Asked Answered
T

3

8

I'm creating a WPF TimeCard app using the MVVM design pattern, and I'm trying to display the sum (total) hours the user has clocked in grouped by each day. I have a ListView with all of the TimeCard data broken into groups using the following XAML:

<ListView.GroupStyle>
    <GroupStyle ContainerStyle="{StaticResource GroupItemStyle}">
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Name, StringFormat=\{0:D\}}" FontWeight="Bold"/>
                    <TextBlock Text="  (" FontWeight="Bold"/>
                    <!-- This needs to display the sum of the hours -->
                    <TextBlock Text="{Binding ???}" FontWeight="Bold"/>
                    <TextBlock Text=" hours)" FontWeight="Bold"/>
                </StackPanel>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListView.GroupStyle>

Is this even possible? At first I thought I would create a partial class of the CollectionViewGroup and add my own properties. But I'm not sure this will even work. Perhaps there is a better solution... any suggestions?

Text answered 6/2, 2010 at 4:11 Comment(0)
B
20

To expand on what e.tadeu said, you can bind your HeaderTemplate's DataTemplate to the Items property of the CollectionViewGroup. This will return you all of the items that are in the current group.

Then you can supply a converter that will return you the desired data from that collection of items. In your case, you say you want the sum of the hours. You could implement a converter that does something like:

public class GroupHoursConverter : IValueConverter
{

    public object Convert(object value, System.Type targetType, 
                          object parameter, 
                          System.Globalization.CultureInfo culture)
    {
        if (null == value)
            return "null";

        ReadOnlyObservableCollection<object> items = 
              (ReadOnlyObservableCollection<object>)value;

        var hours = (from i in items
                     select ((TimeCard)i).Hours).Sum();

        return "Total Hours: " + hours.ToString();
    }

    public object ConvertBack(object value, System.Type targetType, 
                              object parameter, 
                              System.Globalization.CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }
}

Then you could use this converter on your data template:

    <Window.Resources>
        <local:GroupHoursConverter  x:Key="myConverter" />
    </Window.Resources>

    <ListView.GroupStyle>
        <GroupStyle ContainerStyle="{StaticResource GroupItemStyle}">
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Name, 
                                                  StringFormat=\{0:D\}}" 
                                   FontWeight="Bold"/>
                        <TextBlock Text="  (" FontWeight="Bold"/>
                        <!-- This needs to display the sum of the hours -->
                        <TextBlock Text="{Binding Path=Items, 
                                         Converter={StaticResource myConverter}}"
                                   FontWeight="Bold"/>
                        <TextBlock Text=" hours)" FontWeight="Bold"/>
                    </StackPanel>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </ListView.GroupStyle>

Cheers!

Bihari answered 10/2, 2010 at 16:47 Comment(1)
Thanks! I always forget all the things you can do w/ ValueConverters. Thanks for the sample code.Text
I
1

Use a Converter.

See:

http://www.codeproject.com/KB/WPF/WPFAggregateConverter.aspx

This might help you too:

http://www.codeproject.com/KB/WPF/DsxGridCtrl.aspx

Irradiant answered 10/2, 2010 at 15:1 Comment(1)
Thanks... although the answer you gave was also correct, I decided to give it to NathanAW because of the code he provided as it fit directly into my solution.Text
H
-2

Just use "ItemCount" in GroupStyle to show current count of containing items, per this tutorial on ListView grouping.

Hence answered 28/10, 2015 at 12:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.