我正在尝试提高我的 WPF 应用程序的性能,但我在使用复杂的 ItemsControl 时遇到了问题。虽然我已经添加了虚拟化,但仍然存在性能问题,我想我已经找到原因了。
每个项目都包含一系列可扩展区域。因此,用户在开始时会看到摘要,但可以通过展开来向下钻取以查看更多信息。这是它的样子:
如您所见,有一些嵌套的 ItemsControl。所以每个顶级项目都有一堆隐藏控件。虚拟化可防止加载屏幕外的项目,但不会阻止项目本身内的隐藏项目。因此,相对简单的初始布局需要花费大量时间。在其中一些 View 中滑动,87% 的时间花在了解析和布局上,加载需要几秒钟。
我宁愿在用户决定(如果!)时需要 200 毫秒来展开,而不是 2 秒来加载整个页面。
真心求教。但是,我想不出使用 MVVM 添加控件的好方法。 WPF 是否支持任何扩展器或基于可见性的虚拟化,或者我是否会创建自己的实现?
87% 的数字来自诊断:
最佳答案
如果你有
- Expander
Container
some bindings
- Expander
Container
some bindings
+ Expander
+ Expander
... invisible items
那么是的,Container
和所有绑定(bind)在显示 View 时初始化(并且 ItemsControl
为可见项目创建 ContentPresenter
)。
如果你想在 Expander
折叠时虚拟化它的内容,那么你可以使用数据模板
public ObservableCollection<Item> Items = ... // bind ItemsControl.ItemsSource to this
class 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
之外什么都没有被加载。一旦它被扩展(通过用户或以编程方式), View 就会创建视觉效果。
关于c# - 有没有办法通过隐藏面板或扩展器使用虚拟化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38097750/