【问题标题】:WPF rendering slow performanceWPF 渲染性能缓慢
【发布时间】:2013-01-24 11:41:48
【问题描述】:

我正在尝试提高我的树视图在 WPF 中的性能,当您打开一个包含 6000 个子节点的节点时,当前显示它大约需要 13 秒。我正在为子集合使用 observablecollection,数据模板绑定到 TransactionViewModel 类型,该类型有大约 7 列,每列从视图模型中提取一条数据。

创建并实例化了 6000 个子节点的事务视图模型,但由于您还没有直观地显示它们中的任何一个,所以第一次展开节点时,需要 13 秒才能显示。如果您随后收缩并展开节点,它会立即显示,显示/加载时间为零。我能看到的唯一区别是 TransactionviewModel 的每个绑定依赖项属性第一次都有它由 XAML 绑定调用的 getter,而当您第二次重新展开时,这一切都没有发生,因为没有任何改变所以 WPF 没有再次调用 getter,大概只是将绑定信息保存在内存中,以备第二次扩展时使用。

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

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

8s 来渲染 6000 个空白行对我来说似乎很高。是否有任何主要原因导致这种情况发生,或者在将 XAML 从数据模板呈现为树视图时需要注意什么?我试过只使用一个空的数据模板 - 即其中甚至没有一个空白网格,它仍然需要 7 秒。

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

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

非常感谢

【问题讨论】:

  • 您在使用虚拟化吗?当您开始渲染数千个 UI 对象时,WPF 确实会减慢速度,因此通常您只想渲染可见项目,而不是所有项目,并在滚动时简单地替换控件后面的 DataContext。我还会仔细检查以确保是 UI 渲染导致延迟,而不是加载数据。

标签: wpf performance


【解决方案1】:

在我看来,您需要在 TreeView 中启用虚拟化。

来自Optimizing Performance: Controls

默认情况下,为 ListView 和 ListBox 启用 UI 虚拟化 控制它们的列表项何时绑定到数据。树视图 虚拟化可以通过设置启用 VirtualizingStackPanel::IsVirtualizing 附加属性为 true

【讨论】:

【解决方案2】:

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

How to: Improve the Performance of a TreeView

XAML:

<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)

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 那么这仅仅是treeview控件的限制吗?我所做的只是添加空白子节点,这仍然需要相当长的时间。每行的第二个开始包括小图标图像,几乎无法使用。我可以使用什么技巧来加快速度?
    猜你喜欢
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 2010-10-22
    相关资源
    最近更新 更多