简而言之,我的问题是:在WAF中,您更喜欢如何向视图公开经过过滤/排序/分组的ObservableCollections?
我对我的第一次尝试感到相当满意,其中涉及在VM上进行过滤并公开Model对象的ICollectionView以供View绑定:
我对我的第一次尝试感到相当满意,其中涉及在VM上进行过滤并公开Model对象的ICollectionView以供View绑定:
public StartDetailViewModel(IStartDetailView view, StartPoint start, Scenario scenario)
: base(view)
{
this.scenario = scenario;
this.start = start;
this.startsViewSource = new CollectionViewSource();
this.startsViewSource.Filter += new FilterEventHandler(Starts_Filter);
this.startsViewSource.Source = scenario.Starts;
}
public ICollectionView FilteredStarts
{
get
{
return startsViewSource.View;
}
}
void Starts_Filter(object sender, FilterEventArgs e)
{
if (e.Item != null)
{
e.Accepted = (((StartPoint)e.Item).Date == this.start);
}
}
}
然而,直接暴露模型对象是不够的,因为现在每个条目都需要自己的ViewModel。
因此,CollectionViewSource.Source现在附加到一组Views。这样做的主要问题是应用过滤器时:
void Starts_Filter(object sender, FilterEventArgs e)
{
//Since e.Item is now a view we are forced to ask the View for the ViewModel:
StartItemViewModel vm = ((IStartItemView)e.Item).GetViewModel<StartItemViewModel>();
[...]
}
我感觉这种方法不太对,有更好的方法吗?
更新
因此,我回到了使用模型对象的CollectionViewSource.Source,并维护一个独立的子View对象集合,将View绑定到它。
当然,问题是我为什么要在ViewModel中使用CollectionViewSource?
我认为以下原则适用:如果过滤/排序功能仅是View的属性(即备选视图可能合理地不提供此类功能),则应在View中使用CollectionView(必要时使用代码)。如果过滤/排序功能是模型的一部分,则可以通过其他方式在ViewModel或Model中处理。
一旦你意识到在MVVM视图中使用代码是完全可接受的,这就有意义了。
有任何评论吗?