2011-08-03 12 views
48

Tengo idea clara sobre View y ViewModel en el patrón de MVVM. Estoy planeando implementar el patrón MVVM en mi aplicación. Estoy enfrentando un problema con respecto al modelo. Tengo un archivo .xml que se analiza y la información se muestra en la Vista.En el modelo MVVM ¿debería el modelo implementar la interfaz INotifyPropertyChanged?

Necesito ser notificado sobre los cambios en el modelo por primera vez solamente. De aquí en adelante a petición necesito ser notificado.

Entonces, ¿cómo implementar el modelo?

¿Debo implementar la interfaz INotifyPropertyChanged también en la clase de modelo? (He leído que el modelo no debe implementar la interfaz INotifyPropertyChanged, ya que es específico de WPF)

+3

posible duplicado de [En MVVM si el modelo de ViewModel o el modelo implementan INotifyPropertyChanged?] (Http://stackoverflow.com/questions/772214/in-mvvm-should-the-viewmodel-or-model-implement-inotifypropertychanged) –

+0

Definitivamente vale la pena leer la otra pregunta vinculada anteriormente. –

Respuesta

3

No estoy seguro de lo que quiere decir. En la VM, puede tener INotifyPropertyChanged o DependencyProperty-es (en este caso, la VM debe derivar de DependencyObject). No tiene sentido tener ambos. Tampoco tiene sentido no tener ninguno de ellos.

En el modelo, puede hacer lo que desee. La capacidad de disparar/recibir eventos es buena, pero no siempre puedes confiar en ellos. Básicamente, el modelo depende de los datos fuente y de los elementos relacionados, mientras que el modelo de vista tiene la carga de interfaz del modelo con la capa de presentación. Dado que WPF trabaja en eventos, al menos, la VM debe proporcionar algún mecanismo de notificación.

12

El enfoque MVVM estándar es implementar INotifyPropertyChanged solo en ViewModel. El objetivo es actualizar los enlaces apropiados en la Vista cuando algo cambia en ViewModel.

Sin embargo, esto se dirige a los cambios al ViewModel por la Vista. Es decir, cuando cambia el valor en TextBox, la implementación INotifyPropertyChanged en ViewModel actualizará los enlaces relacionados, por lo que la vista se actualiza correctamente.

Hace no cambios de cubierta realizados en el Modelo por una fuente externa, como cambios en la Base de datos u otra interfaz. Siempre que todas las modificaciones de datos provengan de la Vista, ViewModel debe conocer todos los cambios y saber qué actualizar. Por ejemplo, si sabe que cambiar la variable Foo en su Modelo también cambiará el valor de Bar en su Modelo, sería aconsejable llamar tanto a OnPropertyChanged(Foo) como a OnPropertyChanged(Bar) en su ViewModel cuando cambie el valor de Foo.

La otra alternativa es usar eventos entre el modelo y el modelo de vista para actualizar esos valores en el modelo de vista que requieren actualización. Si, como dices, la notificación se requiere "solo por primera vez", entonces la implementación de un manual una vez que se actualice el disparador también debería funcionar.

7

A veces es aceptable que el modelo implemente la interfaz INotifyPropertyChanged.

Por ejemplo, si el modelo tiene muchas propiedades para visualizar y desea evitar implementar una gran cantidad de código (propiedades de proxy) en el modelo de vista para exponer dichas propiedades de modelo.

Mira http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

9

Este es un problema muy común cuando se trabaja con MVVM, INotifyPropertyChanged WPF no es específica, ya que es parte de System.ComponentModel así que no hay necesidad de añadir ninguna referencia específica WPF en ti solución.

Si va a implementar INofityPropertyChanged en su modelo, puede ahorrar mucho más código en ViewModel (Proxy Properties). Entonces, es aceptable que el modelo tenga INotifyPropertyChanged.

40

Implementación INotifyPropertyChanged en modelos es totalmente aceptable -

Típicamente, el modelo implementa las instalaciones que hacen que sea fácil se unen a la vista. Esto generalmente significa que admite la propiedad y la notificación de cambio de la colección a través de las interfaces INotifyPropertyChanged y INotifyCollectionChanged. Las clases de modelos que representan colecciones de objetos normalmente derivan de la clase ObservableCollection<T>, que proporciona una implementación de la interfaz INotifyCollectionChanged.

A pesar de su hasta usted para decidir si desea que el tipo de aplicación o no, pero recuerda -

¿Qué pasa si las clases del modelo no implementan las interfaces necesarias?

A veces será necesario trabajar con los objetos del modelo que no implementar el INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo, o INotifyDataErrorInfo interfaces. En esos casos, el modelo de vista puede necesitar envolver los objetos modelo y exponer las propiedades requeridas en la vista. Los valores para estas propiedades serán proporcionados directamente por los objetos del modelo. El modelo de vista implementará las interfaces requeridas para las propiedades que expone de manera que que la vista pueda vincular fácilmente a ellos.

Tomado de - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx

He trabajado en algunos proyectos en los que no han implementado INotifyPropertyChanged en nuestros modelos y debido a esto nos enfrentamos a una gran cantidad de problemas; la duplicación innecesaria de propiedades era necesaria en VM y al mismo tiempo tuvimos que actualizar el objeto subyacente (con valores actualizados) antes de pasarlos a BL/DL.

Te enfrentarás a problemas especialmente si necesitas trabajar con la colección de tus objetos modelo (por ejemplo, en una grilla o lista editable) o modelos complejos; los objetos modelo no se actualizarán automáticamente y tendrás que administrar todo eso en tu máquina virtual.

+1

Eche un vistazo a http://polymod.codeplex.com/. Puede tener su modelo como POCO, envolverlo con un proxy Polymod que le proporciona INotifyPropertyChanged e incluso IDataErrorInfo listos para usar. Ahorra mucha codificación en su Model/ViewModel. – Arnaud

+0

Gracias Arnaud, parece un marco muy útil. – akjoshi

+0

¿Qué harías si estás usando un DTO? ¿Podrías contaminarlo con INotifyPropertyChanged? Traté de compartir algunos modelos implementando esto con Compact Framework y falló – GorillaApe

2

Este es un argumento clásico entre los codificadores MVVM "puros" y otros.

Tiendo a ir por los libros siempre que puedo porque la mayoría de las veces eso tiene sentido. Sin embargo, en ciertos escenarios, la improvisación del código de acuerdo con las necesidades reduce una gran cantidad de código duplicado.

En su caso, puede leer el XML en una clase de modelo y hacer una copia de la clase de modelo al modelo de vista, o copiar las propiedades que desee del modelo al modelo de vista. De esta manera, tiene el control para actualizar la UI/modelo. Si sigue el primer enfoque, debe tener Inotifypropertychanged implemetned en su clase de modelo y es aceptable.

Habiendo dicho que probaría mi mejor nivel para seguir el segundo enfoque porque eso me daría un control preciso sobre todas las propiedades que se muestran/manipulan en la vista. Además, me sentiré mucho mejor de que no estoy rompiendo el patrón MVVM.

Cuestiones relacionadas