WPF DataGrid Grouping with sums and other fields

11,644

You could use a converter that's passed the Items property of the group header e.g.

<Window.Resources>
    <local:GroupsToTotalConverter x:Key="groupsConverter" />
</Window.Resources>

<Expander.Header>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Path=Name}" Margin="5"/>
        <TextBlock Text="total" Margin="5" />
        <TextBlock Text="{Binding Path=Items, Converter={StaticResource groupsConverter}}" Margin="5" />
    </StackPanel>

where the converter performs the calculation and passes back the total as the string for the text block:

public class GroupsToTotalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is ReadOnlyObservableCollection<Object>)
        {
            var items = (ReadOnlyObservableCollection<Object>)value;
            Decimal total = 0;
            foreach (GroupItem gi in items)
            {
                total += gi.Amount;
            }
            return total.ToString();
        }
        return "";
    }

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

As for the description I'd suggest also grouping by that, and writing another converter to pull out the description from the Items in a similar manner to above.

Share:
11,644
Xaphann
Author by

Xaphann

Updated on July 23, 2022

Comments

  • Xaphann
    Xaphann almost 2 years

    I have a DataGrid that is bound to collection and that I want to be grouped. Here is the code

    Collection:

    private string _ID;
    private string _Descript;
    private decimal _Amount;
    public string ID
    {
       get { return _ID; }
       set { _ID = value; NotifyPropertyChanged("ID"); }
     }
     public decimal Amount
     {
       get { return _Amount; }
       set { _Amount = value; NotifyPropertyChanged("Amount"); }
     }
     public string Descript
     {
       get { return _Descript; }
       set { _Descript = value; NotifyPropertyChanged("Descript"); }
      }
    

    C#;

    ListCollectionView groupcollection = new   ListCollectionView(myCollection);
    groupcollection.GroupDescriptions.Add(new PropertyGroupDescription("ID"));
    myDataGrid.ItemsSource = groupcollection;
    

    XAML:

    <DataGrid Name="myDataGrid">
    <DataGrid.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Name}" />
                    </StackPanel>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type GroupItem}">
                                <Expander>
                                    <Expander.Header>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Path=Name}" Margin="5"/>
                                            <TextBlock Text="Count" Margin="5" />
                                            <TextBlock Text="{Binding Path=ItemCount}" Margin="5"/>
                                        </StackPanel>
                                    </Expander.Header>
                                    <ItemsPresenter />
                                </Expander>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </DataGrid.GroupStyle>
    

    This works perfectly but now in the Expander.Header I want to added a summary of a "Amount" and "Descript" value. So for example if there were 3 records in the collection with ID "ABC" each one being 20 and the description for ABC being "My Count" I would want to see;

    ABC My Count total 60 
    

    How would I do that?