WPF渲染速度慢

WPF渲染速度慢,wpf,performance,Wpf,Performance,我正试图在WPF中提高我的treeview的性能,当你打开一个包含6000个子节点的节点时,显示这个节点当前大约需要13秒。我将observablecollection用于子集合,datatemplate绑定到TransactionViewModel类型,该类型大约有7列,每个列从视图模型中提取一段数据 6000个子节点的transactionviewmodels已创建并实例化,但由于您尚未直观地显示其中任何一个,因此第一次展开节点时,需要13秒才能显示。如果随后收缩并展开节点,它将立即显示,显

我正试图在WPF中提高我的treeview的性能,当你打开一个包含6000个子节点的节点时,显示这个节点当前大约需要13秒。我将observablecollection用于子集合,datatemplate绑定到TransactionViewModel类型,该类型大约有7列,每个列从视图模型中提取一段数据

6000个子节点的transactionviewmodels已创建并实例化,但由于您尚未直观地显示其中任何一个,因此第一次展开节点时,需要13秒才能显示。如果随后收缩并展开节点,它将立即显示,显示/加载时间为零。我能看到的唯一区别是,TransactionviewModel的每个绑定依赖项属性第一次被XAML绑定调用时,以及第二次重新展开时,所有这些都不会发生,因为没有任何更改,所以WPF不会再次调用getter,可能只是在第二次扩展时将绑定信息保存在内存中

因此,控件的可视化绘图是即时的,但在您第一次打开它时(即使6000个transactionviewmodel对象已经完全加载到子集合中),纯粹的行渲染需要时间

有趣的是,如果我将datatemplate更改为不绑定到viewmodel对象上的任何依赖项属性,并且只输出一个空白网格,则加载仍然需要8秒。因此,即使没有任何数据绑定调用,树查看器也需要8秒来渲染6000行。再多5秒,每行大约有5个绑定数据列,因此与基本渲染相比,这是一个很小的成本

对我来说,渲染6000个空白行的8s似乎非常高。在从数据模板将XAML呈现到树状视图中时,是否有可能发生这种情况的主要原因或需要注意的事项?我试着只使用一个空的数据模板,即里面甚至没有一个空白的网格,仍然需要7秒钟

考虑到它随后会立即崩溃和扩展,为什么第一次它甚至没有呈现任何XAML或调用任何数据绑定时要花这么长时间

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


非常感谢

您的问题可能不是渲染,而是布局-它必须实例化许多UI元素以找到它们的大小,以便能够正确调整许多UI元素(滑块)的大小,这需要时间。渲染很可能根本不包括在内。

在我看来,您需要在树视图中启用虚拟化

发件人:

默认情况下,为ListView和ListBox启用UI虚拟化 控制其列表项何时绑定到数据。树景 可以通过设置 VirtualzingStackPanel::IsVirtualization将附加属性虚拟化为true

如果TreeView包含许多项,则加载所需的时间可能会导致用户界面出现显著延迟。通过将VirtualzingStackPanel.IsVirtualization attached属性设置为true,可以缩短加载时间。当用户使用鼠标滚轮或拖动滚动条的拇指滚动TreeView时,UI的反应也可能很慢。通过将VirtualzingStackPanel.VirtualizationMode attached属性设置为Recycling,可以在用户滚动时提高TreeView的性能

XAML:


这只是treeview控件的一个限制吗?因为我所做的只是添加空白的子节点,这仍然需要合理的时间。每行的第二行开始包含小图标图像,几乎无法使用。我可以使用哪些技巧来加快速度?您使用的是虚拟化吗?当您开始渲染数千个UI对象时,WPF确实会减慢速度,因此通常您只希望渲染可见项,而不是所有项,并在滚动时简单地替换控件后面的DataContext。我还要再次检查以确保是UI呈现导致延迟,而不是加载数据。在我的情况下,是VirtualzingPanel.IsVirtualization而不是VirtualzingStackPanel::IsVirtualzingLink已失效。。更新
<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)