Чи слід прив'язувати ICollectionView або ObservableCollection


83

Чи слід прив'язувати DataGridдо

ICollectionView = CollectionViewSource.GetDefaultView(collection)

або до

ObservableCollection<T> collection; ???

Яка найкраща практика для MVVM і чому?

Відповіді:


129

Ви завжди прив’язуєтесь до an ICollectionView, незалежно від того, робите це явним чи ні.

Припустимо, що ми маємо

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

У цьому випадку прив’язка до collectionабо до collectionViewє одним і тим самим: механізм прив’язки прив’яжеться до подання колекції за замовчуванням (до якого відповідає посилання collectionView), якщо ви скажете йому прив’язатись collection.

Це означає, що відповідь на ваше запитання: "це абсолютно не має значення".

Щоб бути абсолютно зрозумілим: навіть якщо ви прив'язуєтесь до колекції безпосередньо, механізм прив'язки прив'язуватиметься до подання за замовчуванням. Модифікація властивостей подання, таких як критерії сортування, впливатиме на прив’язку, яка, здається, прив’язується безпосередньо до колекції, оскільки за обкладинками це прив’язка до подання за замовчуванням.

Однак є ще одне цікаве і пов’язане питання: чи слід прив’язуватись до подання колекції за замовчуванням (тобто до самої колекції, оскільки немає причин явно пов’язувати її до подання за замовчуванням) або до іншого подання тієї ж колекції?

Враховуючи, що кожне представлення має своє поняття поточного елемента, критерії сортування тощо, випливає, що якщо ви маєте намір мати кілька прив’язок до однієї колекції, а зв’язані елементи керування повинні мати різні поняття поточного елемента, фільтрів та компанії, тоді що ви хочете, це явно прив’язати до декількох подань однієї і тієї ж базової колекції.


1
Чудова відповідь. Я вважаю за краще прив'язати ObservableCollection тепер, коли він є частиною System.Collections, і "відчуває" себе більш репрезентативним щодо чогось, що я представляю про Модель, на відміну від View, але MVVM іноді спритний.
Берріл

Створіть відповідь. Я хотів би лише зазначити, що в Silverlight типовий CollectionView за замовчуванням не буде створений для зв'язаних колекцій, якщо ця зв'язана колекція не реалізує ICollectionViewFactory.
jspaey

Це також / як і раніше застосовується до універсальних програм?
Роберт Маклін

@RobertMacLean: Я не маю досвіду розробки WP, тому, на жаль, не маю ідеї.
Джон

Щоб створити явне подання для базової колекції в xaml, створіть елемент CollectionViewSource у Ресурсах. Маючи зв’язок властивості CollectionViewSource.Source з базовою колекцією. Потім прив’яжіть властивість ItemsControl.ItemSource до CollectionViewSource, який ви створили в ресурсі за допомогою StaticResource. Таким чином, операція сортування / фільтрування / групування, застосована до одного подання, не забруднює інші елементи керування, які є прив’язуючими до DefaultView CollectionView.
Frank Liu

35

ObservableCollection<T>реалізує INotifyCollectionChangedта повідомлятиме інтерфейс користувача, коли елементи у колекції будуть змінені.

ICollectionViewнадасть вам можливість фільтрувати, сортувати або групувати колекцію на додаток до INotifyCollectionChangedподій, що розповсюджуються, якщо основна колекція це реалізує.

Будь-який тип добре працює з MVVM, якщо ви до нього прив’язані. Використовуйте, ICollectionViewколи вам потрібно сортувати, фільтрувати або групувати. Використовуйте ObservableCollection<T>безпосередньо, коли ні.


Цей інший допис, судячи з усього, суперечить тому, що ICollectionView автоматично оновлюється на основі події, зміненої колекцією ... це неправильно? stackoverflow.com/a/17906474/3195477
UuDdLrLrSs

@UuDdLrLrS, якщо елементи в колекції змінені, інтерфейс користувача, який прив'язаний до цих елементів, або властивості цих елементів, буде оновлено без необхідності викликати Refresh у колекції. Інший допис конкретно запитує про зміну властивостей елементів у колекції та автоматичне активацію оновлення ICollectionView, щоб переконатися, що він включає лише ті елементи, які все ще відповідають критеріям фільтра. Виходячи з відповіді в іншому дописі, вам доведеться викликати метод Refresh (), щоб оновити "список" елементів у колекції.
Джиммі Р. Хаутс,

9

Просто щоб додати до того, що сказав Джон. Головна відмінність полягає в тому, що, використовуючи CollectionViewSource.GetDefaultView(collection), ви ставите залежність ViewModel від WPF. Багатьом пуристам MVVM це не подобається, і це залишило б ObservableCollection лише дійсним варіантом.

Іншим варіантом буде використання ICollectionViewта використання класу, який реалізує його, але не є частиною самого WPF.


1
Це не головна різниця. Зверніть увагу на тег wpf. "[якщо] зв’язані елементи керування повинні мати чітке уявлення про поточний товар, фільтри та компанію, тоді ви хочете явно прив’язати до декількох подань однієї базової колекції". У цьому різниця. Будучи "пуристом", яким би він не був, означає, що ви не можете фільтрувати тощо. Дивіться відповідь Jimmie Houts, яка зосереджується на фактичній різниці в більш зрозумілій мові.
Dirk Bester

7

Я не думаю, що він повинен щось робити із MVVMсобою. ICollectionViewнадає додаткові функції , такі як Söring угруповання і т.д. , якщо вам потрібно використовувати ті , в IColectionViewіншому випадку просто використовуватиObservableCollection


2

Ви повинні прив’язатись до подання, якщо хочете, щоб ваша сітка відображала налаштування, застосовані до подання, наприклад, фільтрування, інакше подання зайве.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.