Pytanie Należy powiązać z ICollectionView lub ObservableCollection


Jeśli się zwiąże DataGrid do

ICollectionView = CollectionViewSource.GetDefaultView(collection)

lub do

ObservableCollection<T> collection; ???

Jaka jest najlepsza praktyka dla MVVM i dlaczego?


70
2018-06-11 18:50


pochodzenie




Odpowiedzi:


ty zawsze powiązać z ICollectionViewbez względu na to, czy jest to wyraźne, czy nie.

Załóżmy, że mamy

var collection = new ObservableCollection<string>();
var collectionView = CollectionViewSource.GetDefaultView(collection);

W tym przypadku wiążące collection lub collectionView jest jeden i ten sam: silnik wiązania będzie wiązał się z domyślnym widokiem kolekcji (który jest równy collectionView), jeśli powiesz mu, że chcesz się połączyć collection.

Oznacza to, że odpowiedź na twoje pytanie brzmi "nie ma absolutnie żadnej różnicy".

Aby być całkowicie zrozumiałym: nawet jeśli wiążesz się bezpośrednio z kolekcją, silnik wiążący zwiąże się z domyślnym widokiem. Modyfikowanie właściwości widoku, takich jak kryteria sortowania, wpłynie na powiązanie, które wydaje się wiązać bezpośrednio z kolekcją, ponieważ zamiast okładek jest to wiązanie do domyślnego widoku.

Istnieje jednak inne ciekawe i pokrewne pytanie: czy należy powiązać domyślny widok kolekcji (tj. Z samą kolekcją, ponieważ nie ma powodu, aby jawnie wiązać się z domyślnym widokiem) lub z innym widokiem tego samego zbioru?

Biorąc pod uwagę, że każdy widok ma swoje własne pojęcie bieżącego elementu, kryteria sortowania, itp., Oznacza to, że jeśli zamierzasz mieć wiele powiązań z tą samą kolekcją, a powiązane formanty muszą mieć różne pojęcia bieżącego elementu, filtrów i firmy, to to, czego chcesz, to jawne powiązanie z wieloma widokami tej samej kolekcji podstawowej.


112
2018-06-11 19:14



Niesamowita odpowiedź. Moja własna preferencja polega na związaniu się z ObservableCollection teraz, gdy jest częścią System.Collections i "czuje się" bardziej reprezentatywną dla czegoś, co reprezentuję w Modelu, w przeciwieństwie do Widoku, ale czasami MVVM jest czuły w tym sensie. - Berryl
Odpowiedź Greate. Chciałbym tylko zwrócić uwagę, że w Silverlight domyślny CollectionView nie zostanie utworzony dla powiązanych kolekcji, chyba że ta związana kolekcja implementuje ICollectionViewFactory. - jspaey
Czy to też / nadal ma zastosowanie w aplikacjach Universal? - Robert MacLean
@RobertMacLean: Nie mam żadnego doświadczenia w tworzeniu WP, więc niestety nie mam pojęcia. - Jon
Aby utworzyć jawny widok dla kolekcji bazowej w Xaml, utwórz element CollectionViewSource w Zasobach. Posiadanie powiązania właściwości CollectionViewSource.Source z kolekcją źródłową. Następnie należy powiązać właściwość ItemsControl.ItemSource ze źródłem CollectionViewSource utworzonym w zasobach za pośrednictwem StaticResource. W ten sposób operacja sortowania / filtrowania / grupowania zastosowana do jednego widoku nie "zanieczyszcza" innych ItemsControls, które są powiązane z Default CollectionView. - Frank Liu


ObservableCollection<T> przybory INotifyCollectionChanged i powiadomi UI, gdy elementy w kolekcji zostały zmienione.

ICollectionView da ci możliwość filtrowania, sortowania lub grupowania kolekcji oprócz propagowania INotifyCollectionChanged zdarzenia, jeśli kolekcja podstawowa je implementuje.

Oba typy działają dobrze z MVVM tak długo, jak się z nimi wiąże. Posługiwać się ICollectionView kiedy potrzebujesz sortowania, filtrowania lub grupowania. Posługiwać się ObservableCollection<T> bezpośrednio, gdy tego nie robisz.


29
2018-06-11 19:01





Wystarczy dodać do tego, co powiedział Jon. Główną różnicą jest to, że przy użyciu CollectionViewSource.GetDefaultView(collection)robisz ViewModel zależny od WPF. Wielu purystów MVVM tego nie lubi, a to zostawiłoby ObserveableCollection tylko ważną opcję.

Inną opcją byłoby użycie ICollectionView i użyj klasy, która ją implementuje, ale nie jest częścią samej WPF.


9
2018-06-11 20:40



Jednak to nie jest główna różnica. Zwróć uwagę na tag wpf. "[Jeśli] kontrolki powiązane muszą mieć różne pojęcia o bieżącym elemencie, filtrach i firmie, to właśnie to, co chcesz, to jawne powiązanie z wieloma widokami tej samej kolekcji". Taka jest różnica. Bycie "purystą", cokolwiek to jest, oznacza, że ​​nie możesz filtrować itp. Zobacz odpowiedź Jimmiego Houts, która koncentruje się na faktycznej różnicy w jaśniejszym języku. - Dirk Bester


Nie sądzę, żeby to miało coś z tym wspólnego MVVM samo. ICollectionView zapewnia dodatkowe funkcje, takie jak grupowanie zasobów itp., jeśli potrzebujesz tego zastosowania IColectionView poza tym po prostu użyj ObservableCollection


6
2018-06-11 19:03





Wiązałoby się widok, jeśli chcesz, aby twoja siatka wyświetlała ustawienia zastosowane do widoku, np. filtrowanie, w przeciwnym razie widok jest zbędny.


2
2018-06-11 18:54