XAMLのObservableCollection
にバインドし、そこにグループ化したいと考えました。原則として、これはうまくいきました。 XAMLで定義されているCollectionViewを取得するには
<UserControl.Resources>
<CollectionViewSource x:Key="cvs" Source="{Binding Path=TestTemplates}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Title"/>
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="TestCategory"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
は、その後、データバインディング式は
ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}"
の代わり
ItemsSource="{Binding Path=TestTemplates}"
となりました。
ビューモデルからUIをリフレッシュするまで、最初はすべてがクールだと思われました。問題は、CollectionViewSource.GetDefaultView(TestTemplates)
が、グループ化が適用されたXAMLのビューとは異なるビューを返したことです。したがって、私は選択をすることができなかったし、それに役立つものは何もしなかった。
リストを直接ビューモデルのプロパティにバインドし、コードビハインドでグループを設定することで修正できます。しかし、私はこの解決策に満足していません。
private void UserControlLoaded(object sender, RoutedEventArgs e)
{
IEnumerable source = TemplateList.ItemsSource;
var cvs = (CollectionView)CollectionViewSource.GetDefaultView(source);
if (cvs != null)
{
cvs.SortDescriptions.Add(new SortDescription("Title", ListSortDirection.Ascending));
cvs.GroupDescriptions.Add(new PropertyGroupDescription("TestCategory"));
}
}
私はその理由がすでにgiven by John Skeet hereであると仮定します。
しかし、私は正しい見方をする方法があるはずです。私が間違っている?
あなたは間違った方向に向かっています。 VMはビューの知識がないはずです。ビューを更新する場合は、バインドするプロパティがObservableCollectionであることを確認するか、コレクションを変更するときにNotifyPropertyChangedを明示的に呼び出します。 –
@PanagiotisKanavos:リストビュー内のものは実際にはObservableCollection内に*あり、UI内の項目はプロパティの変更時に更新されます。しかし、グループ分けはそれを尊重しない。回避策としては、強制的に更新を行うこと、つまり 'CollectionViewSource.GetDefaultView(...).Refresh'があります。 – primfaktor
.NET 4.5では、これは[ICollectionViewLiveShaping](http://msdn.microsoft.com/en-us/library/system.componentmodel.icollectionviewliveshaping(v = vs.110).aspx)で修正されます。 – primfaktor