我正在开发一个应用程序,其中我的大部分内容通过内置的 WPF
DataGrid
呈现给用户。这是我的 DataGrid
的样子。除了父 Grid
上的 RowDefinitions
之外,我没有设置任何东西。
<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 文件中)。没有额外的 ScrollViewers
、StackPanels
或任何东西。就是这个。
<RibbonWindow>
<Grid>
<ContentControl> <!-- Populated via a DataTemplate and ContentTemplateSelector -->
<UserControl>
<UserControl>
<UserControl>
<Grid>
<Here is the DataGrid>
一些我试图加快加载速度的东西
- 明确设置所有列宽(将我的加载时间缩短约 10 秒)
- 关闭
AutoGenerateColumns
(没有任何影响)。 - 禁用
DataGrid 的
RessourceDictionary
中设置的样式(无区别) - 使用异步/等待和其他多线程策略在后台线程上将项目加载到我的
ObservableCollection
中。这对加载时间没有影响。 - 将项目添加到新的
ObservableCollection
,然后将其设置为数据绑定(bind)属性(因此不会触发事件) - 一次向
ObservableCollection
添加项目(每次添加都会触发事件) - 打开和关闭虚拟化不会影响加载时间。
我知道延迟不是由填充 ObservableCollection
引起的。它在集合完全填充后开始,当 WPF
DataGrid
呈现所有行/列时。我启用了虚拟化,但它仍然需要很长时间。我使用的是 .NET Framework 4.5.1(因此 Virtualization
的 4.6 问题不是导致此问题的原因)。从 UI 进行排序(使用内置数据网格排序)和调整列大小时,也存在长时间延迟。
我在这里错过了什么?我可以做些什么来确保 Virtualization
正常工作吗?有哪些事情可以加快速度?如果我知道 Virtualization
正在运行,那么我可能会转向新的策略,例如分页或某种延迟加载。我愿意使用的另一种解决方案是在呈现所有行时用户界面不被阻止/卡住的解决方案。这样一来,用户至少可以在添加行的同时点击其他东西。
最佳答案
DataGrid
元素上的 ScrollViewer.CanContentScroll
值必须设置为 True
才能使行虚拟化正常工作。 Here is an explanation为什么必须这样设置。
感谢ChrisW在这个问题的评论中发现这一点。
关于c# - WPF DataGrid 似乎没有虚拟化行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44786431/