WPF DataGrid似乎没有虚拟化行

时间:2017-06-27 17:28:56

标签: c# .net wpf xaml wpfdatagrid

我正在处理一个应用程序,其中我的大部分内容都通过内置的WPF DataGrid呈现给用户。这是我DataGrid的样子。我不会在父RowDefinitions上设置Grid以外的任何内容。

<UserControl xmlns="blah blah blah">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition Height="Auto"/>
     </Grid.RowDefinitions>

  <DataGrid x:Name="dgrMaterialCollection" 
          IsReadOnly="True" 
          ItemsSource="{Binding Path=MyObservableCollection, UpdateSourceTrigger=PropertyChanged}" 
          AutoGenerateColumns="True" 
          AutoGeneratingColumn="dgrMaterialCollection_AutoGeneratingColumn"
          AutoGeneratedColumns="dgrMaterialCollection_AutoGeneratedColumns"
          CanUserResizeColumns="True" 
          CanUserReorderColumns="True"
          CanUserSortColumns="True"
          EnableRowVirtualization="True"
          EnableColumnVirtualization="True"
          VirtualizingPanel.IsVirtualizingWhenGrouping="True"
          VirtualizingPanel.VirtualizationMode="Standard"
          VirtualizingPanel.IsVirtualizing="True"
          SelectionMode="Single"
          SelectionUnit="FullRow"
          ScrollViewer.CanContentScroll="False"
          RowHeaderWidth="0" 
          Grid.Row="0"
          RowHeight="32"
          RowDetailsVisibilityMode="Collapsed">
  <DataGrid.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="DataGridStyle.xaml"/>
      </ResourceDictionary.MergedDictionaries>

      <!-- A few value converters -->
     </ResourceDictionary>
   </DataGrid.Resources>
   <!-- Some Manually Declared Columns -->
  </DataGrid>
  <StackPanel Grid.Row="1">
    <SomeTextBoxes/>
  </StackPanel>
 </Grid>
</UserControl>

当我的应用程序显示DataGrid时,根据数据集的大小,大约有10-20秒的延迟。在此延迟期间,UI被锁定。加载数据网格后 - 我可以毫不拖延地滚动浏览所有数千个项目。当我毫不拖延地说,我的意思是点击滚动条并尽可能快地上下移动它,在滚动时不会延迟渲染行。看起来虚拟化不起作用,而数据网格一次创建所有行而不是用户滚动时。

我的Datagrid嵌套在以下结构中(分布在多个xaml文件中)。没有额外的ScrollViewersStackPanels或其他任何内容。就是这样。

<RibbonWindow>
  <Grid>
    <ContentControl> <!-- Populated via a DataTemplate and ContentTemplateSelector -->
      <UserControl>
        <UserControl>
          <UserControl>
            <Grid>
              <Here is the DataGrid> 

我试图加快加载的一些事情

  • 明确设置所有列宽(削减加载时间约10秒)
  • 关闭AutoGenerateColumns(没有任何区别)。
  • 禁用DataGrid's RessourceDictionary中设置的样式(无差异)
  • 使用async / await和其他多线程策略将项目加载到后台线程中的ObservableCollection。这对加载时间没有影响。
  • 将项目添加到新ObservableCollection,然后将其设置为数据绑定属性(因此事件未被触发)
  • 一次向ObservableCollection添加一个项目(每次添加时触发事件)
  • 打开和关闭虚拟化对加载时间没有影响。

我知道延迟不是由填充ObservableCollection引起的。它在完全填充集合后启动,并在WPF DataGrid呈现所有行/列时启动。我已启用虚拟化,但仍需要永久性。我正在使用.NET framework 4.5.1(因此Virtualization的4.6问题不会导致此问题)。排序时(使用内置的数据网格排序)和从UI调整列的大小也会有很长的延迟。

我在这里缺少什么?我能做些什么来确保Virtualization正在运作吗?有什么东西可以加快这个速度?如果我知道Virtualization正在运行,那么我可能会采用新的策略,例如分页或某种延迟加载。我愿意使用的另一个解决方案是在呈现所有行时不阻塞/冻结用户界面的解决方案。这样,当添加行时,用户至少可以点击其他内容。

1 个答案:

答案 0 :(得分:0)

ScrollViewer.CanContentScroll元素上的DataGrid值必须设置为True才能使行虚拟化正常运行。 Here is an explanation为什么必须这样设定。

感谢ChrisW在此问题的评论中发现了这一点。