我正在实现一个WPF DataGrid,其中包含具有许多关键指标的项目。项目按项目类别分组。

对于每个类别,应该有:

  • 在每一关键指标列中显示一行,以显示该列所有行的总和。
  • 绑定(bind)到的目标行,该目标行不属于数据源网格。目标行告诉每一列该年度的目标(例如,要花费多少钱)。

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

    我的第一个解决方案是在组头中包含此数据。这不是一个好的解决方案,因为组头不支持列。即应通过获取列宽来构造它。

    可以这样做,但是当用户要重新排序和隐藏列时,它变得很复杂。

    DataGrid使用的是CollectionViewSource,因此未填充C#代码。基本上,我在扩展此示例:http://msdn.microsoft.com/en-us/library/ff407126.aspx

    致以最诚挚的问候-Matti

    最佳答案

    我的一个项目中有一起被黑客入侵的DataGrid,其中包含分组小计行。我们并不担心您提出的一些问题,例如隐藏和对列进行排序,因此我不确定是否可以扩展它。我还意识到,可能存在性能问题,这可能是大型设备的问题(我的窗口正在运行32个单独的DataGrids-ouch)。但这是与我所见过的其他解决方案不同的方向,所以我想我把它放在这里,看看它是否对您有帮助。

    我的解决方案包含2个主要组件:
    1.小计行不是主DataGrid中的行,而是单独的DataGrid。我实际上在每个组中有2个额外的网格:仅在该组折叠时在标题中显示1个,在ItemsPresenter下显示一个。小计数据网格的ItemsSource来自一个Converter,该Converter获取组中的项目并返回聚合 View 模型。小计网格的列与主网格完全相同(填写在DataGrid_Loaded中,尽管我确定它也可以在xaml中完成)。

                <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.接下来的问题是如何使所有DataGrid像单个网格一样运行。我通过在名为DataGridTextColumn的类中将DataGridSharedSizeTextColumn(在这种情况下,我们只有文本,但其他列类型也应该工作)子类化来解决这一问题,该类模仿Grid类的SharedSizeGroup行为。它具有带有组名的字符串依赖项属性,并跟踪同一组中的所有列。当一列中Width.DesiredValue更改时,我在所有其他列中更新MinWidth,并使用DataGridOwner.UpdateLayout()强制进行更新。此类还涉及列的重新排序,并且每当DisplayIndex更改时,都会在整个组范围内进行更新。我认为只要有 setter ,此方法也可以与其他任何列属性一起使用。

    还有其他烦人的事情需要选择,复制等来解决。但是事实证明,使用MouseEntered和MouseLeave事件以及使用自定义的Copy命令非常容易处理。

    关于c# - 如何处理小计WPF DataGrid中的目标行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10652203/

    10-11 04:09