ItemsControl.ItemsSource MVVM 性能

发布于 2024-08-25 19:42:25 字数 494 浏览 6 评论 0原文

我有一个(非虚拟化)ItemsControl,它将其 ItemsSource 绑定到 ViewModel 实例的 ObeservableCollection。现在,一旦加载大量 Model 实例,所有 ViewModel 补充都需要添加到该 ObservableCollection 中。如何添加大量 ViewModel 而不会导致 UI 线程挂起?

我想 UI 线程会挂起,因为每次添加新项目时,ItemsControl 都需要更新自身并一遍又一遍地进行布局等。

  • 我是否应该暂停绑定添加所有 项目然后恢复?如果是这样,怎么办?
  • 我应该覆盖 ObservableCollection 来实现 AddRange 所以只有 1 个 CollectionChanged 添加多个时会触发事件 项目?或者只是替换 整个集合?
  • 或者更好 分别添加每个项目并调用 Dispatcher.Invoke 每个项目 分别地?所以我会解锁 频繁地。

如何处理无法虚拟化的大型动态列表?

I have an (non-virtualized) ItemsControl that binds its ItemsSource to a ObeservableCollection of ViewModel instances. Now once the large amount Model instances is loaded all the ViewModel complemnents needs to be added to that ObservableCollection. How can I add a large amount of ViewModels without making the UI Thread hang?

I suppose the UI Thread hangs because each time a new item is added the ItemsControl needs to update itself and does layout etc. over and over again.

  • Should I suspend the binding add all
    items and then resume? If so, how?
  • Should I override the
    ObservableCollection to implement an
    AddRange so only 1 CollectionChanged
    Event is fired for adding multiple
    items? Or alternatively just replace
    the whole collection?
  • Or is it better
    to add each items separately and call
    Dispatcher.Invoke for each item
    separately? So I would unblock
    frequently.

How do you handle large dynamic lists that can not be virtualized?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

宁愿没拥抱 2024-09-01 19:42:25

您可以创建一个派生自 ObservableCollection 的类,该类允许您暂时挂起 < href="http://msdn.microsoft.com/en-us/library/ms653375.aspx" rel="noreferrer">CollectionChanged 事件如下:

public class SuspendableObservableCollection : ObservableCollection
{
    private bool suspended;

    public bool Suspended 
    {
        get
        {
            return this.suspended;
        }
        set
        {
            this.suspended = value;
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Reset));
        }
    }

    protected override void OnCollectionChanged(
        NotifyCollectionChangedEventArgs args)
    {
       if (!Suspended)
       {
           base.OnCollectionChanged(args);
       }
    }
}

You can create a a class derived from ObservableCollection which allows you to temporarily suspend CollectionChanged events like this:

public class SuspendableObservableCollection : ObservableCollection
{
    private bool suspended;

    public bool Suspended 
    {
        get
        {
            return this.suspended;
        }
        set
        {
            this.suspended = value;
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Reset));
        }
    }

    protected override void OnCollectionChanged(
        NotifyCollectionChangedEventArgs args)
    {
       if (!Suspended)
       {
           base.OnCollectionChanged(args);
       }
    }
}
狼亦尘 2024-09-01 19:42:25
<ItemsControl IsAsync="True" ... />
<ItemsControl IsAsync="True" ... />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文