2

我有一个 DataGrid,它有一个 CollectionViewSource 绑定到它的 ItemSource 属性:

<DataGrid Grid.Row="0" RowBackground="#10808080" AlternatingRowBackground="Transparent"
          HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
          ItemsSource="{Binding Source={StaticResource bookingsViewSource}}"
          RowHeight="27"
          VirtualizingPanel.IsVirtualizingWhenGrouping="True"
          VirtualizingPanel.IsContainerVirtualizable="True"
          VirtualizingPanel.ScrollUnit="Item"
          AutoGenerateColumns="False">

    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding date, StringFormat=dd.MM.yyyy}" Header="date"/>
        <DataGridTextColumn Binding="{Binding Path=customers.name}" Header="customer"/>
        <DataGridTextColumn Binding="{Binding Path=customers.street}" Header="adress"/>
    </DataGrid.Columns>

    <DataGrid.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Expander Header="{Binding Path=Name}" IsExpanded="True">
                                    <ItemsPresenter />
                                </Expander>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </DataGrid.GroupStyle>
</DataGrid>

bookingsViewSource定义为

<CollectionViewSource x:Key="bookingsViewSource"
                      d:DesignSource="{d:DesignInstance {x:Type Database:bookings}}">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="providerID"/>
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

并填写后面部分的代码。在没有分组的情况下,一切都做得很好。但是当我添加分组时<PropertyGroupDescription PropertyName="providerID"/>,DataGrid 需要大约一分钟才能加载。

在 .NET 4.5 中有一个名为的新属性VirtualizingPanel.IsVirtualizingWhenGrouping,我已经将其设置为 true,但加载时间并没有减少。

我不知道为什么。有任何想法吗?

4

1 回答 1

6

来自书中:MacDonald M. - C# 中的 Pro WPF 4.5

许多因素可能会破坏 UI 虚拟化,有时在您意料之外的情况下:

  • 将列表控件放入 ScrollViewer:ScrollViewer 为其子内容提供一个窗口。问题是子内容被赋予了无限的“虚拟”空间。在这个虚拟空间中,ListBox 以全尺寸呈现自身,并显示其所有子项。作为副作用,每个项目都有自己的占用内存的 ListBoxItem 对象。每当您将 ListBox 放置在不尝试限制其大小的容器中时,都会出现此问题。例如,如果您将其弹出到 StackPanel 而不是 Grid 中,则会出现同样的问题。
  • 更改列表的控件模板并且无法使用 ItemsPresenter:ItemsPresenter 使用 ItemsPanelTemplate,它指定了 VirtualizingStackPanel。如果您打破这种关系,或者您自己更改 ItemsPanelTemplate 使其不使用 VirtualizingStackPanel,您将失去虚拟化功能。
  • 不使用数据绑定:这应该很明显,但是如果您以编程方式填充列表(例如,通过动态创建所需的 ListBoxItem 对象),则不会发生虚拟化。当然,您可以考虑使用自己的优化策略,例如只创建您需要的那些对象,并且只在需要时创建它们。在第 22 章中,您将看到使用即时节点创建来填充目录树的 TreeView 的这种技术。如果您有一个很大的列表,则需要避免这些做法以确保良好的性能。

此外,就我而言,问题是由MahApps.Metro样式引起的。

于 2015-12-23T14:52:00.140 回答