带分组的WPF DataGrid虚拟化

Jan*_*ter 22 .net wpf virtualization grouping datagrid

我正在使用CodePlexWPF DataGrid,我需要让Virtualization与分组一起使用.

这个问题是关于主题并指向MSDN示例,但它仅涵盖带有简单(即单个"列")DataTemplates的ListControls.

分组和虚拟化似乎是网格的一个非常常见的用例.是否有标准/推荐/简单的方法来实现这一目标?

Sco*_*ott 34

我意识到我在这里迟到了...但我最近遇到了这个问题(使用.NET 4中内置的DataGrid).不幸的是,一旦在DataGrid上使用Grouping,仍然没有行的虚拟化...但是我发现了一个非常光滑的性能增强技巧,希望其他人也会觉得有用.

假设您在GroupItem模板的扩展器中使用ItemsPresenter,并且默认情况下您的扩展器未展开,那么尝试使用默认的BooleanToVisibilityConverter将ItemsPresenter的可见性绑定到Expander的IsEnabled属性:

<BooleanToVisibilityConverter x:Key="bool2vis" />


<DataGrid.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <Expander x:Name="exp">
                                <ItemsPresenter Visibility="{Binding ElementName=exp, Path=IsExpanded, Converter={StaticResource bool2vis}}" />
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</DataGrid.GroupStyle>
Run Code Online (Sandbox Code Playgroud)

如果您遇到DataGrid需要很长时间加载的问题(因为它实际上是在数据网格中抽出每条记录,即使它在折叠的扩展器中)...然后使用上面的代码会导致数据网格不能绘制您的记录,直到您展开一个组,然后,它将只绘制该特定组的记录.

缺点是,这只有在默认情况下折叠扩展器时才有用,并且仍然没有虚拟化行(如果扩展组中有100个项目,但屏幕上只有20个项目,则所有100个项目都将在你扩大团队的时间).

好处是你实际上已经实现了延迟加载DataGrid记录,因此在实际需要查看项目(您选择展开组)之前,您不会执行绘图工作.对于我的产品,我的组头包含内置按钮以对其组内的所有项执行操作,因此除非用户需要对组内的单个项执行操作,否则用户通常不会扩展组.

*如果使用此技巧,需要注意的一点是,您应该为列标题设置一些显式宽度或最小宽度(因为在DataGrid首次加载时不会绘制项目,因此列标题无法自动调整以适应最大的项目).

希望真正的虚拟化能够在未来的服务包中实现,但如果没有,我希望这将有助于其他人!

更新

看来这个问题将在.NET 4.5中修复,并附带一个新的附加属性VirtualizingPanel.IsVirtualizingWhenGrouping.

  • 如果只有我可以投票两次......一举惊人的性能提升 (4认同)
  • 这真棒!我有一个地方每次都会失去记忆,这就像一个魅力! (2认同)

Iva*_*anH 15

框架4.5 VirtualizingPanel.IsVirtualizingWhenGrouping中有一个新的附加属性,允许在分组时打开虚拟化.

<DataGrid EnableColumnVirtualization="True" EnableRowVirtualization="True"
   VirtualizingPanel.IsVirtualizingWhenGrouping="True">
Run Code Online (Sandbox Code Playgroud)


jap*_*apf 0

正如您所说,启用分组将禁用 UI 虚拟化。

我认为您不会找到解决此问题的简单方法。我建议您检查可用的 WPF DataGrid 之一,例如XCeeed,它可能在其控件中内置了此功能。