C# · 12月 23, 2021

c# – 有没有办法使用隐藏面板或扩展器的虚拟化?

我正在尝试使用我的 WPF应用程序来提高性能,并且我遇到了复杂的ItemsControl问题.虽然我已经添加了虚拟化,但仍然存在性能问题,我想我已经解决了原因.

每个项目都包含一系列可扩展区域.因此,用户在开始时会看到摘要,但可以通过展开来查看更多信息.以下是它的外观:

如您所见,有一些嵌套的ItemsControls.所以每个顶级项目都有一堆隐藏控件.虚拟化可防止加载屏幕外项目,但不会阻止项目本身内的隐藏项目.结果,相对简单的初始布局花费了大量时间.轻击其中一些视图,87%的时间用于解析和布局,加载需要几秒钟.

我宁愿用200ms来扩展用户决定的时间(如果!),而不是2s来加载整个页面.

真的要求建议.我想不出使用MVVM添加控件的好方法. WPF是否支持任何扩展器或基于可见性的虚拟化,或者我是否会创建自己的实现?

87%的数字来自诊断:

解决方法 如果你只是 – Expander Container some bindings – Expander Container some bindings+ Expander+ Expander… invisible items

然后是,在显示视图时初始化Container和所有绑定(ItemsControl为可见项创建ContentPresenter).

如果要在Expander折叠时虚拟化Expander的内容,则可以使用数据模板

public ObservableCollection<Item> Items = … // bind ItemsControl.ItemsSource to thisclass Item : INotifyPropertyChanged{ bool _isExpanded; public bool IsExpanded // bind Expander.IsExpanded to this { get { return _isExpanded; } set { Data = value ? new SubItem(this) : null; OnPropertyChanged(nameof(Data)); } } public object Data {get; private set;} // bind item Content to this}public SubItem: INotifyPropertyChanged { … }

我希望没有必要解释如何在xaml中对SubItem进行数据模板化.

如果你这样做,那么最初Data == null并且除了Expander之外什么也没有加载.一旦扩展(通过用户或编程),视图将创建视觉效果.