如何处理组小计,例如WPF DataGrid 中的目标行? [英] how to handle group subtotal and e.g. target rows in WPF DataGrid?

查看:21
本文介绍了如何处理组小计,例如WPF DataGrid 中的目标行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实施一个 WPF DataGrid,其中包含具有许多关键数字的项目.项目按项目类别分组.

I'm implementing a WPF DataGrid that contains projects with many key figures. Projects are grouped by project categories.

对于每个类别应该有:

  1. 在每个关键指标列中显示该列所有行的总和的行.
  2. 不属于绑定到的数据源网格的一部分的目标行.目标行告诉每一列今年的目标是什么(例如要花多少钱).

这些行应始终位于每个组的顶部(排序过滤).

These rows should be always on top in each group (sorting filtering).

我的第一个解决方案是在组标题中包含这些数据.这不是一个好的解决方案,因为组标题不支持列.即它应该通过获取列宽来构建.

My 1st solution was to have this data in group header. This is not a good solution because group header does not support columns. i.e. it should be constructed by getting column widths.

这可以做到,但当用户想要重新排序和隐藏列时,它会变得复杂.

That could be done but it gets complicated when users want to reorder and hide columns.

DataGrid 正在使用 CollectionViewSource,因此它没有填充 C# 代码.基本上我正在扩展这个例子:http://msdn.microsoft.com/en-us/library/ff407126.aspx

DataGrid is using CollectionViewSource so it's not populated with C# code. Basically i'm extending this example: http://msdn.microsoft.com/en-us/library/ff407126.aspx

谢谢&最好的问候 - 马蒂

Thanks & Best Regards - matti

推荐答案

我在我的一个项目中有一个组合在一起的 DataGrid,其中包含分组小计行.我们不关心您提出的一些问题,例如隐藏和排序列,所以我不确定是否可以为此进行扩展.我也意识到可能存在性能问题,这可能是大型集合的问题(我的窗口正在运行 32 个独立的 DataGrid - 哎哟).但它与我见过的其他解决方案的方向不同,所以我想我会把它扔在这里,看看它是否对你有帮助.

I have a hacked-together DataGrid with group subtotal rows in one of my projects. We weren't concerned about some of the issues you bring up, such as hiding and sorting columns so I don't know for sure if it can be extended for that. I also realize there could be performance issues that may be a problem with large sets (my window is operating 32 separate DataGrids - ouch). But it's a different direction from other solutions I've seen, so I thought I'd throw it up here and see if it helps you out.

我的解决方案由两个主要部分组成:
1. 小计行不是主 DataGrid 中的行,而是单独的 DataGrid.我实际上在每个组中有 2 个额外的网格:1 个在标题中,仅在组折叠时显示,一个在 ItemsPresenter 下方.小计 DataGrids 的 ItemsSource 来自一个 Converter,它接受组中的项目并返回一个聚合视图模型.小计网格的列与主网格完全相同(在 DataGrid_Loaded 中填写,但我确信它也可以在 xaml 中完成).

My solution consists of 2 major components:
1. The subtotal rows aren't rows in the main DataGrid, but are separate DataGrids. I have 2 extra grids in each group actually: 1 in the header that is only displayed when the group is collapsed, and one beneath the ItemsPresenter. The ItemsSource for the subtotal DataGrids comes from a Converter that takes the items in the group and returns an aggregate view model. The columns of the subtotal grids are exactly the same as the main grid (filled out in DataGrid_Loaded, though I'm sure it could be done in xaml too).

            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander Background="Gray" HorizontalAlignment="Left" IsExpanded="True"
                                              ScrollViewer.CanContentScroll="True">
                                        <Expander.Header>
                                            <DataGrid Name="HeaderGrid" ItemsSource="{Binding Path=., Converter={StaticResource SumConverter}}"
                                                        Loaded="DataGrid_Loaded" HeadersVisibility="Row"
                                                        Margin="25 0 0 0" PreviewMouseDown="HeaderGrid_PreviewMouseDown">
                                                <DataGrid.Style>
                                                    <Style TargetType="DataGrid">
                                                        <Style.Triggers>
                                                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded}"
                                                                            Value="True">
                                                                <Setter Property="Visibility" Value="Collapsed"/>
                                                            </DataTrigger>
                                                        </Style.Triggers>
                                                    </Style>
                                                </DataGrid.Style>
                                            </DataGrid>
                                        </Expander.Header>
                                        <StackPanel>
                                            <ItemsPresenter/>
                                            <DataGrid Name="FooterGrid" ItemsSource="{Binding ElementName=HeaderGrid, Path=ItemsSource, Mode=OneWay}"
                                                            Loaded="DataGrid_Loaded" HeadersVisibility="Row"
                                                            Margin="50 0 0 0">
                                                <DataGrid.Style>
                                                    <Style TargetType="DataGrid">
                                                        <Style.Triggers>
                                                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded}"
                                                                         Value="False">
                                                                <Setter Property="Visibility" Value="Collapsed"/>
                                                            </DataTrigger>
                                                        </Style.Triggers>
                                                    </Style>
                                            </DataGrid>
                                        </StackPanel>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>


2. 那么问题是如何让所有的 DataGrids 表现得好像它们是一个单一的网格.我已经通过在一个名为 DataGridSharedSizeTextColumn 的类中子类化 DataGridTextColumn(在这种情况下我们只有文本,但其他列类型也应该工作)来处理这个问题,该类模仿了网格类.它有一个带有组名的字符串依赖属性,并跟踪同一组中的所有列.当一列中的 Width.DesiredValue 发生变化时,我会更新所有其他列中的 MinWidth 并使用 DataGridOwner.UpdateLayout() 强制更新.此类还涵盖列重新排序,并在 DisplayIndex 更改时进行组范围更新.我认为这个方法也适用于任何其他列属性,只要它有一个 setter.


2. Then the issue is how to get all DataGrids to behave as if they were a single grid. I've handled that by subclassing DataGridTextColumn (we only have text in this case, but other column types should work too) in a class called DataGridSharedSizeTextColumn that mimics the SharedSizeGroup behavior of the Grid class. It has a string dependency property with a group name and keeps track of all columns in the same group. When Width.DesiredValue changes in one column, I update the MinWidth in all the other columns and force an update with DataGridOwner.UpdateLayout(). This class is also covering column reordering and does a group-wide update whenever DisplayIndex changes. I would think this method would also work with any other column property as long as it has a setter.

还有其他烦人的事情需要处理选择、复制等.但结果证明,使用 MouseEntered 和 MouseLeave 事件以及使用自定义复制命令非常容易处理.

There were other annoying things to work out with selection, copying, etc. But it turned out to be pretty easy to handle with MouseEntered and MouseLeave events and by using a custom Copy command.

这篇关于如何处理组小计,例如WPF DataGrid 中的目标行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆