我在mz ViewModel中有一个可观察的项目集合,比如说
public ObservableCollection<T> Items {get;private set;}
我在View中使用没有问题。我想创建一个这个集合的投影,这也是可观察的。像
这样的东西public IEnumerable<T> ProjectedItems
{
get
{
Items.OrderByDescending(l=>l.SomeProperty).Take(SomeAmount);
}
}
这个想法是当Items更改时,ProjectedItems也会改变(重新评估LINQ表达式)。有没有办法实现这个目标?
答案 0 :(得分:1)
有关
public ObservableCollection<T> Items {get;private set;}
public IEnumerable<T> ProjectedItems {get;private set;}
似乎有效的解决方案是订阅CollectionChanged
ObservableCollection
事件并重新评估LINQ表达式:
Items.CollectionChanged += (s, e) => ProjectedItems = Items.OrderByDescending(l=>l.SomeProperty).Take(SomeAmount);
答案 1 :(得分:1)
首先,如果您正在执行绑定,请不要使用IEnumerable<T>
,因为延迟执行可能会产生一些有趣的副作用。请改用IList
或ICollection
。
也就是说,您应该根据原始集合的变化频率和变更时间来设计策略,以确定有多少项目会发生变化。如果更改的数量很多,那么自己实际处理元素的提取可能会更高效,否则只要原始集合发生更改,您就可以简单地重新构建列表。
答案 2 :(得分:0)
有CollectionViewSource来对ObservableCollection的项进行分组,过滤和排序(如果你启用&#34; live&#34;分组/过滤/排序,则动态),但据我所知无法在ObservableCollections
上使用所有LINQ运算符。
您可以实现自己的INotifyCollectionChanged
包围现有的ObservableCollection
,对其应用一些方法(例如Take
或OrderBy
),并触发CollectionChanged
每当包装的集合发生时。