¿Debo vincularme a ICollectionView u ObservableCollection?

83

¿Debería uno unirse DataGrida la

ICollectionView = CollectionViewSource.GetDefaultView(collection)

o al

ObservableCollection<T> collection; ???

¿Cuál es la mejor práctica para MVVM y por qué?

Cartesius00
fuente

Respuestas:

129

Usted siempre se enlaza a una ICollectionView, si usted lo hace explícita o no.

Supongamos que tenemos

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

En este caso, la vinculación hacia collectiono hacia collectionViewes una y la misma: el motor de vinculación se vinculará a la vista de colección predeterminada (que es la referencia igual a collectionView) si le dice que se vincule collection.

Esto significa que la respuesta a su pregunta es "no hace ninguna diferencia".

Para ser totalmente claro: incluso si se vincula a la colección directamente, el motor de vinculación se vinculará a la vista predeterminada. La modificación de las propiedades de la vista, como los criterios de clasificación, afectará el enlace que parece enlazar directamente con la colección, ya que detrás de las cubiertas es un enlace a la vista predeterminada.

Sin embargo, hay otra pregunta interesante y relacionada: ¿debería uno vincularse a la vista de colección predeterminada (es decir, a la colección en sí, porque no hay razón para vincularse explícitamente a la vista predeterminada) oa otra vista de la misma colección?

Teniendo en cuenta que cada vista tiene su propia noción de elemento actual, criterios de clasificación, etc., se deduce que si tiene la intención de tener múltiples enlaces a la misma colección, y los controles vinculados deben tener nociones distintas de elemento actual, filtros y compañía, entonces lo que desea es enlazar explícitamente a varias vistas de la misma colección subyacente.

Jon
fuente
1
Respuesta impresionante. Mi propia preferencia es unirme a ObservableCollection ahora que es parte de System.Collections y "se siente" más representativo de algo que estoy representando sobre el Modelo en oposición a la Vista, pero MVVM es delicado de esta manera a veces.
Berryl
Gran respuesta. Solo me gustaría señalar que en Silverlight no se creará un CollectionView predeterminado para las colecciones vinculadas a menos que esa colección vinculada implemente ICollectionViewFactory.
jspaey
¿Es esto también / sigue siendo aplicable a las aplicaciones universales?
Robert MacLean
@RobertMacLean: No tengo ninguna experiencia en desarrollo de WP, así que desafortunadamente no tengo idea.
Jon
Para crear una vista explícita para una colección subyacente en xaml, cree un elemento CollectionViewSource en Resources. Tener la propiedad CollectionViewSource.Source vinculada a la colección subyacente. Luego vincule su propiedad ItemsControl.ItemSource a CollectionViewSource que creó en el recurso a través de StaticResource. De esta manera, la operación de clasificación / filtro / agrupación aplicada a una vista no "contaminará" otros ItemsControls que están vinculados a Default CollectionView.
Frank Liu
35

ObservableCollection<T>implementa INotifyCollectionChangedy notificará a la interfaz de usuario cuando se hayan cambiado los elementos de la colección.

ICollectionViewle dará la capacidad de filtrar, ordenar o agrupar la colección además de propagar INotifyCollectionChangedeventos si la colección subyacente lo implementa.

Cualquiera de los dos tipos funciona bien con MVVM siempre que se vincule a él. Úselo ICollectionViewcuando necesite ordenar, filtrar o agrupar. Úselo ObservableCollection<T>directamente cuando no lo haga.

Jimmie R. Houts
fuente
Esta otra publicación parece contradecir que ICollectionView se actualizará automáticamente en función de un evento de cambio de colección ... ¿es incorrecto? stackoverflow.com/a/17906474/3195477
UuDdLrLrSs
@UuDdLrLrSs si se modifican los elementos de la colección, la interfaz de usuario que está vinculada a esos elementos, o las propiedades de esos elementos, se actualizará sin la necesidad de llamar a Refresh en la colección. La otra publicación pregunta específicamente sobre el cambio de propiedades de los elementos de la colección y activa automáticamente una actualización de ICollectionView para asegurarse de que solo incluya elementos que aún coincidan con los criterios del filtro. Según la respuesta en la otra publicación, tendría que llamar al método Refresh () para actualizar la "lista" de elementos de la colección.
Jimmie R. Houts
9

Solo para agregar a lo que dijo Jon. La principal diferencia es que al usarlo CollectionViewSource.GetDefaultView(collection), hace que ViewModel dependa de WPF. A muchos puristas de MVVM no les gusta esto y esto dejaría a ObservableCollection como la única opción válida.

Otra opción sería usar ICollectionViewy usar una clase, que la implemente, pero que no sea parte de WPF en sí.

Eufórico
fuente
1
Sin embargo, esa no es la principal diferencia. Tenga en cuenta la etiqueta wpf. "[si] los controles vinculados deben tener nociones distintas de elemento actual, filtros y empresa, entonces lo que desea es vincularse explícitamente a múltiples vistas de la misma colección subyacente". Esa es la diferencia. Ser un "purista", sea lo que sea, significa que no puede filtrar, etc. Vea la respuesta de Jimmie Houts, que se centra en la diferencia real en un lenguaje más claro.
Dirk Bester
7

No creo que tenga que ver nada consigo MVVMmismo. ICollectionViewproporciona características adicionales como agrupación de soring, etc., si las necesita, de lo IColectionViewcontrario, simplemente useObservableCollection

Haris Hasan
fuente
2

Debería vincularse a la vista si desea que su cuadrícula muestre la configuración aplicada a la vista, por ejemplo, filtrado; de lo contrario, la vista es redundante.

devdigital
fuente