我正在实现一个WPF DataGrid,其中包含具有许多关键指标的项目。项目按项目类别分组。
对于每个类别,应该有:
这些行应始终位于每个组的顶部(排序过滤)。
我的第一个解决方案是在组头中包含此数据。这不是一个好的解决方案,因为组头不支持列。即应通过获取列宽来构造它。
可以这样做,但是当用户要重新排序和隐藏列时,它变得很复杂。
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/