Group Sub-Totals

Jan 16, 2009 at 9:54 AM
Hi,

How can I add a sub total of a numeric (currency) column to a DataGrid Grouping?


Thanks
Coordinator
Jan 19, 2009 at 1:45 PM
If you are using the built in CollectionView for grouping, one way to accomplish this is through a converter.  Let's say that the GroupStyle looks like this:

<GroupStyle
x:Key="gs_Default">
    <GroupStyle.Panel>
        <ItemsPanelTemplate>
            <dg:DataGridRowsPresenter/>
        </ItemsPanelTemplate>
    </GroupStyle.Panel>
    <GroupStyle.HeaderTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Padding="3"/>
                <TextBlock Text="{Binding Converter={StaticResource SubTotalConverter}}" FontWeight="Bold" Padding="3"/>
            </StackPanel>
        </DataTemplate>
    </GroupStyle.HeaderTemplate>
</GroupStyle>

In the converter, you will gain access to the CollectionViewGroup item which has information about the number of items it holds, it's name, and the actual items within the group.  You can do the subtotal calculation with that information. 
Jan 21, 2009 at 8:51 PM
Thanks that is exactly what I needed to know. It's so easy when you know how!!!

I had already looked at your DataGridCTPSample and had the basics in place.

The grouping that I am doing takes a while to execute (~12 seconds, I have about 1600 records in my test table and I am grouping on a time/date column). Is that to be expected? I have a decent specification PC that I am testing on - dual core processor with 4GB RAM.
Jan 22, 2009 at 7:38 PM
Hi again, I have added an expander to the group style (which starts off not expanded) and now it groups very quickly! So I have some clues now and a line of investigation.
Mar 14, 2009 at 1:43 PM
Hi,

This kind of solution looks close to what I need to implement a single 'totals' rows in my DataGrid. However, I want to add the totals row below the other items, as shown in this crude ASCII diagram. I will only need total information for some of the numeric column data.

Col A      | Col B |  Col C  |     Col D    |  Col E 
-------------------------------------------------
Name A  |    4     |    45.5  |   Some text |     34.3
Name B  |    5     |    23.5  |   Some text |     23.6
Name C  |    2    |     34.2  |   Some text |    22.1
------------------------------------------------
Total           11                                          80.0

Can this be done with the template for the GroupStyle, as described by vinsibal, or can the total information only appear in the header for the subgroup? If that is the case, I guess perhaps I could place the total information in a second subgroup and force that to appear below the group for the individual items (and disable sorting on that column).

Basically, I'm new to the DataGrid and GroupStyles and am trying to figure how best to achieve this?

Vinsibal or ChangedDaily, could you expand on your solution any more than you have done so above? That would be really helpful as I feel like I'm missing something.

The alternative is to look at the posts about implementing a footer. Is this functionality planned to be added to the datagrid?

Thanks,

Max


Coordinator
Mar 18, 2009 at 9:54 PM
You can use ItemsPanelTemplate of GroupStyle.Panel to put the footer. Some thing like following should work for you....

<GroupStyle x:Key="gs_Default">
    <GroupStyle.Panel>
        <ItemsPanelTemplate>
            <StackPanel>
                <dg:DataGridRowsPresenter/>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Padding="3"/>
                    <TextBlock Text="{Binding Converter={StaticResource SubTotalConverter}}" FontWeight="Bold" Padding="3"/>
                </StackPanel>
            </StackPanel>
        </ItemsPanelTemplate>
    </GroupStyle.Panel>
</GroupStyle>
Apr 7, 2009 at 5:58 PM
Thanks for the reply. I actually handled this in the end by creating an extended data object for the datagrid which has an IsTotal boolean field. I then applied grouping to the data in the grid, and sorted the groups on this field. I was able to keep the position fixed as a footer by hiding the column the IsTotal field was mapped to, so that the sort order would alway place it at the bottom. Finally, the group style for the header was set to something that took up no space, making it appear as if the data is all one group.

Max