WPF StackPanel 性能 [关闭]
Posted
技术标签:
【中文标题】WPF StackPanel 性能 [关闭]【英文标题】:WPF StackPanel performance [closed] 【发布时间】:2021-12-26 23:24:21 【问题描述】:我们使用 WPF 编写了一个新项目,但在最初的几次测试之后,我注意到当 ComboBox 元素的数据源中有数千个对象时,它们的性能很差。我解决了(在向我的新老板祈祷之后)使用:
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
我想知道 StackPanel 控件是否会出现这种带有数百个自定义元素的问题(UserControl 只有一个标签和两个按钮)。 UserControl(s) 以这种方式添加到应用程序中的两个/树位置的代码中:
foreach (var obj in myList)
MyUserControl muc = new MyUserControl(obj);
myStackPanel.Add(muc);
谁能告诉我我们是否会遇到问题和/或是否有办法告诉 StackPanel 重用缓存对象?
附:我是一名 Apple Swift 开发人员,刚刚进入 Windows,完成了一项可怕的新工作......
【问题讨论】:
您已经遇到了问题。为了得到你问题的明确答案,我建议你自己测试一下。即使有人对可能发生的事情有意见,它也可能不适用于您的情况。 @MartinLiversage 是的,我知道,但在家里我什至没有电脑……只有 M1 Mac…… 【参考方案1】:我假设当您谈论在StackPanel
中显示“几百个自定义元素”时,您想添加滚动条以使所有元素都适合屏幕。
一般的问题是,一次渲染许多项目(或其容器)会影响渲染性能,正如人们所期望的那样。您的ComboBox
已经遇到过这个问题。
您想要的只是为可见项目创建容器,而不是为所有数百或数千个项目创建容器。这称为 UI 虚拟化。 UI虚拟化的核心是ScrollViewer
和VirtualizingStackPanel
(或一般的VirtualizingPanel
),其中ScrollViewer
定义可见区域,VirtualizingPanel
控制基于滚动输入的容器生成/回收。
您很可能希望将StackPanel
替换为ListBox
。ListBox
垂直堆叠项目并默认具有ScrollViewer
(StackPanel
没有)。由于ListBox
的默认Panel
是VirtualizingStackPanel
,因此它支持UI 虚拟化(默认启用),因此让您在不影响渲染性能的情况下显示“无限”项(只要这些项的可视化树容器并不过分复杂)。
另外,尽量不要一件一件地添加物品。这将触发完整的渲染过程,尤其是对于不支持 UI 虚拟化的控件,例如 StackPanel
。尝试一次或至少分批添加所有项目,这对于 StackPanel 是不可能的。它是错误主机的另一个原因。
Optimizing performance: Controls
【讨论】:
你明白了(我接受了你的回答)。 StackPanel 已经是 Scroller 的子项。由于我对这个平台缺乏了解(在 macOS 中,我永远不会使用 NSTableView 对象这样做)我想知道我所遭受的这种方法是否是由于某种无知,我真的很难说服老板。与此同时,我在这里发现了一些有趣的解决方案:***.com/a/1525874/3123201 您发布的链接正是正确的方法。 “正常”的 WPF 方法是创建数据模型列表。如果这个列表是动态变化的,你可以使用 ObservableCollection。然后在数据绑定的帮助下,您可以将此数据模型集合绑定到 ListBox(绑定到 ItemsSource 属性)。然后,您将为数据模型定义一个 DataTemplate。此模板可以包含与数据模型相关的 UserControl。这样,WPF 将为您生成容器和用户控件。那么你问题中的循环将是多余的。 Data binding overview (WPF .NET), Data Templating Overview. 关于您发布的链接:不要使用 ItemsControl,而是使用 ListBox。 ListBox 扩展了 ItemsControl,但默认添加了滚动和 UI 虚拟化支持。它更先进。 WPF 是数据驱动的。您总是希望专注于数据模型并让 WPF 基于 DataTemplates 动态创建 UI 元素。以上是关于WPF StackPanel 性能 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
WPF 中的 StackPanel 和 DockPanel 有啥区别?