【问题标题】:ObservableCollection projections that is also observable也是可观察的 ObservableCollection 投影
【发布时间】:2014-02-28 07:49:47
【问题描述】:

我在 mz ViewModel 中有一个可观察的项目集合,比如说

public ObservableCollection<T> Items {get;private set;}

我在视图中使用没有问题。我想创建这个集合的投影,这也是可观察的。类似的东西

public IEnumerable<T> ProjectedItems
{
   get 
   {
        Items.OrderByDescending(l=>l.SomeProperty).Take(SomeAmount);
   }
}

这个想法是,当 Items 发生变化时,ProjectedItems 也会发生变化(重新评估 LINQ 表达式)。有没有办法做到这一点?

【问题讨论】:

    标签: c# linq windows-phone-8 collections observablecollection


    【解决方案1】:

    对于

    public ObservableCollection<T> Items {get;private set;}
    public IEnumerable<T> ProjectedItems  {get;private set;}
    

    似乎可行的解决方案是订阅ObservableCollectionCollectionChanged 事件并重新评估LINQ 表达式:

    Items.CollectionChanged += (s, e) => ProjectedItems = Items.OrderByDescending(l=>l.SomeProperty).Take(SomeAmount);
    

    【讨论】:

      【解决方案2】:

      首先,如果您正在执行绑定,请不要使用IEnumerable&lt;T&gt;,因为延迟执行可能会产生一些有趣的副作用。请改用IListICollection

      也就是说,您应该围绕原始集合更改的频率以及更改时更改的项目数量来制定策略。如果更改的数量很大,您自己实际处理元素的提取可能会更高效,否则您可以在原始集合发生更改时简单地重建列表。

      【讨论】:

        【解决方案3】:

        CollectionViewSource 可以对 ObservableCollection 的项目进行分组、过滤和排序(如果启用“实时”分组/过滤/排序,则动态地),但据我所知,没有办法使用全部 LINQ 运算符在ObservableCollections

        您可以实现自己的 INotifyCollectionChanged,它包裹现有的 ObservableCollection,对其应用一些方法(例如 TakeOrderBy),并在包裹的集合执行时触发 CollectionChanged

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多