要するに、私の質問は次のとおりです。フィルタリング/ソート/グループ化された ObservableCollections を WAF のビューにどのように公開したいですか?
VM でのフィルタリングと、View をバインドする Model オブジェクトの ICollectionView の公開を含む、最初の試みにかなり満足しました。
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);
}
}
}
ただし、Model オブジェクトを直接公開するだけでは不十分です。これは、各アイテムが独自の ViewModel を必要とするためです。
そのため、CollectionViewSource.Source がビューのコレクションにアタッチされるようになりました。これに関する主な問題は、フィルターを適用するときです。
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>();
[...]
}
これは私には間違っているように感じます。より良いアプローチはありますか?
アップデート
そこで、Model オブジェクトの CollectionViewSource.Source に戻し、View がバインドされた子 View オブジェクトの個別のコレクションを維持しました。
もちろん、問題は、なぜ ViewModel で CollectionViewSource を使用しているのかということです。
次の原則が適用されると思います: フィルタリング/並べ替え機能がビューのみのプロパティである場合 (つまり、代替ビューがそのような機能を正当に提供しない可能性がある場合)、ビューで CollectionViews を使用する必要があります (必要に応じてコード ビハインドを使用)。フィルタリング/並べ替え機能がモデルのディメンションである場合、これは ViewModel またはモデルで他の方法で処理できます。
これは、MVVM ビューでのコード ビハインドが完全に受け入れられることを認識すれば理にかなっています。
コメントはありますか?