WPF DataGrid 虚拟化与分组 [英] WPF DataGrid Virtualization with Grouping

查看:130
本文介绍了WPF DataGrid 虚拟化与分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用来自 CodePlex 的 WPF DataGrid,我需要让 Virtualization 与分组一起工作.

I'm using the WPF DataGrid from CodePlex and I need to get Virtualization to work with grouping.

这个问题是关于主题的,指向一个MSDN 示例,但它仅涵盖具有简单(即单个列")数据模板的 ListControl.

This question is on topic and points to an MSDN Example but it only covers ListControls with with simple (i.e. single 'column') DataTemplates.

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

Grouping and Virtualization seems like a pretty common use case for a Grid. Is there a standard/recommended/simple way of getting this going?

推荐答案

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

I realize I'm late to the party here... but I ran into this problem recently (using the DataGrid built into .NET 4). Unfortunately, there still is no virtualization of the rows once Grouping is used on the DataGrid... but a I found a very slick performance enhancement trick that hopefully somebody else will find useful as well.

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

Assuming you're using an ItemsPresenter within an expander of your GroupItem's template and by default your expander is not expanded, then try simply binding the visibility of your ItemsPresenter to the Expander's IsEnabled property with the default BooleanToVisibilityConverter:

<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>

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

If you're running into the problem where your DataGrid takes really long to load (because it's essentially drawing out every record in your datagrid even though it's in a collapsed expander)... then using the above code will cause the datagrid to not draw your records until you expand a group, and then, it will only draw out the records for that particular group.

不利的一面是,这仅在您的扩展器默认折叠时才有帮助,并且行仍然没有被虚拟化(如果您在一个扩展组中有 100 个项目,但只有 20 个项目适合屏幕,则所有 100 个项目都将是在您扩展组时绘制).

The down side is that this only helps if your expanders are collapsed by default, and still the rows do not get virtualized (if you have 100 items in an expanded group, but only 20 fit on the screen, all 100 will be drawn at the time you expanded the group).

好处是您基本上实现了 DataGrid 记录的延迟加载,因此在您真正需要查看项目(您选择展开组)之前,您不会执行绘图工作.对于我的产品,我的组标题内置了按钮来对其组内的所有项目执行操作,因此用户通常不会扩展组,除非他们需要对组中的单个项目执行操作.

The upside is that you've essentially implemented lazy loading of your DataGrid records, so you're not performing the drawing work until you actually need to view the items (you choose to expand the group). For my product, my group header had buttons built in to perform operations on all items within its group, so more often the user never expanded a group unless they needed to perform an operation on an individual item within a group.

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

*One thing to note if you use this trick is that you should probably set some explicit widths or minimum widths to your column headers (because the items are not being drawn when the DataGrid first loads, so the column headers cannot autosize to fit the largest item).

希望在未来的服务包中实现真正的虚拟化,但如果没有,我希望这会对其他人有所帮助!

Hopefully true virtualization gets implemented in a future service pack, but if not, I hope this will help somebody else!

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

It appears this issue will be fixed in .NET 4.5 with a new attached property VirtualizingPanel.IsVirtualizingWhenGrouping.

这篇关于WPF DataGrid 虚拟化与分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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