【问题标题】:OnPropertyChanged with a ListOnPropertyChanged 与列表
【发布时间】:2010-09-28 05:14:13
【问题描述】:

我在视图中有一个数据网格,它绑定到视图模型中的列表。我有很多数据要检索列表,所以我想将其分解为许多小检索而不是一个大检索。

我希望这发生在后台线程上,并在检索到的每个批次结束时更新 UI(网格绑定新数据)。

在每次检索结束时,我在私有支持者上执行 List.AddRange(),然后引发 OnPropertyChanged 事件,传递网格绑定到的公共属性的名称。

最初我尝试了 6 次迭代,每次迭代检索 100 个项目。在后台运行时,UI 会在前 100 个之后更新,但不会更新最后 500 个(即使数据已成功添加到视图模型中的底层列表)。

考虑到我在编组到 UI 线程时遇到了一些问题,我同步运行它,期望它按预期工作(尽管在每次检索期间阻塞 UI)或在所有检索期间阻塞 UI - 但在任何一种情况下,最后更新以显示 600 项。但是,它最终会执行与我在后台运行时相同的操作 - 仅更新前 100 个,而不更新其余部分。

以下是我在两次尝试中使用的方法,上半部分是背景版本被注释掉。

我做错了什么?

public void StartDataStream()
{
    //Task<List<Car>> task = _taskFactory.StartNew(this._retrieveData);

    //task.ContinueWith(t =>
    //{
    //    if (this._cars == null) this._cars = new List<Car>();

    //    this._cars.AddRange(t.Result);
    //    base.OnPropertyChanged("Cars");

    //    this.iterations += 1;
    //    if (iterations < 6) StartDataStream();
    //});

    if (this._cars == null) this._cars = new List<Car>();

    this._cars.AddRange(this.GetCarList(eq,s,e));
    base.OnPropertyChanged("Cars");

    this.iterations += 1;

    if (iterations < 6) StartDataStream();
}

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    您是否尝试过使用ObservableCollection&lt;T&gt; 而不是List&lt;T&gt;

    我假设您有一个名为 Cars 的公共财产,类似于...

    public List<Car> Cars{
    
       get { return this._cars;}
       set
       {
          this._cars = value;
          base.OnPropertyChanged("Cars");
       }
    
    }
    

    如果不是这样,这实际上不会做任何事情...base.OnPropertyChanged("Cars");

    AddRange 的扩展方法ObservableCollection

    public static class Extensions
    {
        public static void AddRange(this ObservableCollection obj, List<T> items)
        {
            foreach (var item in items)
              obj.Add(item);
        }
    }
    

    【讨论】:

    • 其实我考虑过但是没有尝试,因为ObservableCollection上缺少AddRange方法。由于没有使用 AddRange 实现我自己的 ObservableCollection,我担心 UI 更新每个项目而不是每 100 个项目的性能。
    • 我在使用 List 而不是 Observable 时遇到了一些问题,当我切换时它似乎玩得更好。 List 类型没有实现 INotifyCollectionChanged,而 Observable 确实实现了它。我会试一试,看看它是否对你有影响。
    • 是的,ObservableCollection 值得一试——我现在就试试。关于公共财产,是的,我的看起来和你那里的完全一样 - 抱歉,我应该在我的例子中包含它。
    • 这很酷,只是想确保您在那里仔细检查:)
    • 好的,所以使用 ObservableCollection,通过同步方法,在所有迭代完成后 UI 更新为 600(显然阻塞了所有迭代)。然后我用 Task 方法做了同样的事情,根本没有得到任何 UI 更新(甚至没有前 100 个) - 所以也许我更接近了,现在我确实对 UI 线程有一个编组问题?
    猜你喜欢
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 2021-12-11
    相关资源
    最近更新 更多