Ich wollte an eine ObservableCollection
in XAML binden und auch die Gruppierung dort anwenden. Im Prinzip hat das gut funktioniert.Wie kann ich die CollectionView, die in XAML definiert ist
<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>
Dann wurde die Datenbindung Ausdruck ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}"
anstelle von ItemsSource="{Binding Path=TestTemplates}"
.
Zuerst schien alles cool, bis ich die Benutzeroberfläche aus dem Ansichtsmodell aktualisieren wollte. Das Problem ist, dass CollectionViewSource.GetDefaultView(TestTemplates)
eine andere Ansicht als die von XAML zurückgegeben hat, wo die Gruppierung angewendet wurde. Daher konnte ich keine Auswahl treffen oder irgendetwas Nützliches damit machen.
Ich könnte es beheben, indem Sie die Liste erneut direkt an die Eigenschaft des Ansichtsmodells binden und die Gruppierung im Code-Behind einrichten. Aber ich bin nicht so glücklich mit dieser Lösung.
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"));
}
}
Ich gehe davon aus, ist der Grund für die bereits given by John Skeet here.
Trotzdem würde ich erwarten, dass es einen Weg geben sollte, um die richtige Sicht zu bekommen. Liege ich falsch?
Sie gehen in die falsche Richtung. Eine VM sollte keine Kenntnis von der Ansicht haben. Wenn Sie die Ansicht aktualisieren möchten, stellen Sie sicher, dass es sich bei der Eigenschaft, an die sie gebunden ist, entweder um eine ObservableCollection oder Ihren Code handelt, der beim Ändern der Auflistung explizit NotifyPropertyChanged ausgelöst hat. –
@PanagiotisKanavos: Das Zeug in der Listenansicht ist tatsächlich * ist * in einer 'ObservableCollection' und die Elemente in der Benutzeroberfläche werden bei einer Änderung der Eigenschaften aktualisiert. Aber die Gruppierung respektiert das nicht. Eine bekannte Problemumgehung besteht darin, das Update zu erzwingen, d.h. 'CollectionViewSource.GetDefaultView (...) .Refresh'. – primfaktor
In .NET 4.5 wird dies mit dem [ICollectionViewLiveShaping] (http://msdn.microsoft.com/en-us/library/system.componentmodel.iclectionviewliveshaping (v = vs.110) .aspx) behoben. – primfaktor