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

标签 c# wpf performance virtualization

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

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

enter image description here

如您所见,有一些嵌套的 ItemsControl。所以每个顶级项目都有一堆隐藏控件。虚拟化可防止加载屏幕外的项目,但不会阻止项目本身内的隐藏项目。因此,相对简单的初始布局需要花费大量时间。在其中一些 View 中滑动,87% 的时间花在了解析和布局上,加载需要几秒钟。

我宁愿在用户决定(如果!)时需要 200 毫秒来展开,而不是 2 秒来加载整个页面。

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

87% 的数字来自诊断:

enter image description here

最佳答案

如果你有

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

相关文章:

c# - 展平可能包含数组的对象数组

wpf - 使用 FlowDocumentScrollViewer 打印所有页面

c# - 更改 key 扩展 WPF 工具包 Zoombox

c# - 如何在加载时关闭 Mahapps.Metro 窗口上的幻灯片动画?

jquery 性能 td 替换

c# - 需要使用 float 来提高性能但需要 double 计算

c# - 找不到 Entity Framework 4 注释

c# - 为什么 Task<TResult>.Result 在这种情况下不起作用?

c# - 将异步回调与 Task.ContinueWith 结合使用

javascript - 使用 props 访问纯文本或数组中的对象路径