WPF渲染性能较慢

13

我正在尝试提高WPF中树形视图的性能。当您打开一个有6000个子节点的节点时,目前需要约13秒才能显示出来。我使用一个ObservableCollection作为子集合,将其与DataTemplate绑定到TransactionViewModel类型,并从视图模型中拉取大约7列数据。

这6000个子节点的TransactionViewModel已经被创建和实例化,但由于您还没有在视觉上显示它们,因此第一次展开节点时需要13秒才能显示。如果您然后收缩并再次展开节点,则会立即显示,不需要任何时间来显示/加载。唯一的区别是,每次XAML绑定调用TransactionviewModel的每个绑定依赖属性的getter方法时,第一次发生了这种情况,而当您第二次重新展开时,由于没有任何更改,所以这些事情都不会再次发生,WPF不再调用getter,可能只是将绑定信息保存在内存中,以备第二次展开时使用。

因此,控件的可视绘制是瞬间完成的,但是第一次打开时(即使这6000个transactionviewmodel对象已经全部加载到子集合中),纯粹的行渲染需要花费时间。

有趣的是,如果我更改DataTemplate以不对视图模型对象上的任何依赖属性进行绑定,只输出一个空白网格,则仍需要8秒钟才能加载。因此,即使没有任何数据绑定调用,树形查看器也需要8秒钟来呈现6000行。每行有5个绑定数据列,则额外5秒给您的成本与基本呈现相比很小。

对我来说,渲染6000个空白行需要8秒钟似乎很高。是否存在任何重要原因导致这种情况发生或在从数据模板呈现XAML到树形视图时要注意的事项?我尝试过只使用空白DataTemplate - 即其中甚至没有一个空白网格,但仍需7秒钟才能完成。

考虑到它然后立即折叠和展开,为什么第一次需要这么长时间,而它甚至没有呈现任何XAML或调用任何数据绑定呢?

此外,异步调用并不是解决方案,因为我的问题不在于GUI响应性,而在于加载数据所花费的时间。用户需要比现在更快地获得数据。

非常感谢


你是否正在使用虚拟化?当你开始呈现成千上万个UI对象时,WPF确实会变慢。因此,通常您只需要呈现可见的项目,而不是所有项目,并在滚动时简单地替换控件后面的DataContext。我还会再次检查确保它是UI渲染引起的延迟,而不是加载数据。 - Rachel
3个回答

12

在我的看法中,你需要在TreeView中启用虚拟化功能。

来自优化性能:控件

默认情况下,当ListView和ListBox控件的列表项绑定到数据时,它们启用UI虚拟化。可以通过将VirtualizingStackPanel::IsVirtualizing附加属性设置为true来启用TreeView虚拟化功能。


在我的情况下,它是VirtualizingPanel.IsVirtualizing而不是VirtualizingStackPanel :: IsVirtualizing。 - Yogesh
2
链接已失效..更新为https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-controls - David Jeske

3
如果TreeView包含许多项,则加载所需的时间可能会导致用户界面显著延迟。您可以通过将VirtualizingStackPanel.IsVirtualizing附加属性设置为true来提高加载时间。当用户使用鼠标滚轮或拖动滚动条的拇指滚动TreeView时,UI 反应也可能很慢。您可以通过将VirtualizingStackPanel.VirtualizationMode附加属性设置为Recycling来提高用户滚动TreeView时的性能。
XAML: 如何:改善TreeView的性能
<TreeView Height="200" ItemsSource="{Binding Source={StaticResource dataItems}}" x:Name="myTreeView" 
        VirtualizingStackPanel.IsVirtualizing="True"
        VirtualizingStackPanel.VirtualizationMode="Recycling"/>

通过编程:

myTreeView.SetValue(VirtualizingStackPanel.IsVirtualizingProperty, true);
myTreeView.SetValue(VirtualizingStackPanel.VirtualizationModeProperty, VirtualizationMode.Recycling)

1
你的问题可能不是渲染,而是布局 - 它必须实例化许多UI元素以找到它们的大小,以便可以正确调整一些UI元素(滑块)的大小,这需要时间。渲染很可能根本没有涉及到这个问题。

2
这只是树形视图控件的限制吗?因为我所做的只是添加空白子节点,但仍需要相当长的时间。第二个问题是,每行开始包含小图标图像时,它几乎无法使用。我可以使用哪些技巧来加快速度? - NZJames

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接