在WPF Datagrid中扩展虚拟化

时间:2012-02-08 16:48:23

标签: wpf performance xaml wpfdatagrid virtualization

我正在处理的原型中存在性能问题。要求是使用多个同步冻结窗格构建数据网格,支持分组和排序等...有关我正在构建的网格的更多详细信息,请参阅this previous question

现在,我有一个与分组有关的问题,特别是扩展器。我有一个由以下Xaml定义的GroupStyle,取自this blog post

    <!--Default GroupStyle-->
    <GroupStyle x:Key="gs_Default">
        <GroupStyle.Panel>
            <ItemsPanelTemplate>
                <DataGridRowsPresenter/>
            </ItemsPanelTemplate>
        </GroupStyle.Panel>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Padding="3"/>
                </StackPanel>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <Expander x:Name="exp"
                                      BorderBrush="#FFA4B97F" 
                                      BorderThickness="0,0,0,1" 
                                      IsExpanded="{Binding Path=Items[0].IsExpanded}">
                                <Expander.Header>
                                    <DockPanel TextBlock.FontWeight="Bold">
                                        <TextBlock Text="{Binding Path=Name}" Margin="5,0,5,0" />
                                        <TextBlock Text="{Binding Path=ItemCount}"/>
                                    </DockPanel>
                                </Expander.Header>
                                <ItemsPresenter/>                       
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>

Expander没有虚拟化,当组中有几百行时,我们遇到了性能问题。

有没有人曾经遇到过这种情况并且有一个修复方法?我理想地寻找虚拟化扩展器,并且已经看到workarounds such as this(它没有解决问题)。

2 个答案:

答案 0 :(得分:3)

如果您正在使用.NET 4,那么获取ItemsPresenter的可见性以跟踪/取决于IsExpanded状态。

在.NET 4.5中,有一个新的附加属性VirtualizingPanel.IsVirtualizingWhenGrouping

另一种方法是将分组推送到ViewModel,而不是让DataGrid / CollectionView对此负责。见这里:

答案 1 :(得分:2)

为了解决这个问题,我们做了以下工作。

我们使用DataTemplates为不同的行视图模型呈现不同的行视图。我们有一个GroupRowViewModel和ItemRowViewModel。也是父ViewModel,它具有Group / Item视图模型的排序列表。

当网格被实例化时,父ViewModel会将所有子视图模型排序为以下内容:

    • 项目
    • 项目
    • 项目
    • 项目
    • 项目
    • 项目

单击GroupRow时,您希望执行一些代码,其中父项(包含组+项目行的排序列表)将删除或包含项目。例如。说点击第二个gropu,你绑定到的rowviewmodel列表现在变为

    • 项目
    • 项目
    • 项目
  • 集团(倒塌)

就是这样。因此,根本不需要任何魔法,您可以手动删除或包含所需的行,具体取决于所点击的内容。它以可接受的速度与虚拟化和数十万行协同工作。

抱歉,我无法发布任何代码(由于NDA),但我希望能帮到你。另外 - 我建议查看Telerik Grid,因为对于大型数据集来说这是非常快的