La mayoría de los ejemplos de MVVM con los que he trabajado han implementado el ModeloINotifyPropertyChanged
, pero en el ejemplo CommandSink de Josh Smith, los implementos ViewModelINotifyPropertyChanged
.
Todavía estoy reuniendo cognitivamente los conceptos de MVVM, así que no sé si:
- Tienes que ponerlo
INotifyPropertyChanged
en ViewModel para ponerteCommandSink
a trabajar - Esto es solo una aberración de la norma y realmente no importa
- Siempre debe tener el modelo implementado
INotifyPropertyChanged
y esto es solo un error que se corregiría si se desarrollara a partir de un ejemplo de código para una aplicación
¿Cuáles han sido las experiencias de otros en los proyectos MVVM en los que has trabajado?
c#
mvvm
inotifypropertychanged
Edward Tanguay
fuente
fuente
Respuestas:
Yo diría todo lo contrario, siempre pongo mi
INotifyPropertyChanged
en mi ViewModel: realmente no quieres contaminar tu modelo con una característica bastante específica de WPF comoINotifyPropertyChanged
, esas cosas deberían estar en el ViewModel.Estoy seguro de que otros no estarían de acuerdo, pero esa es la forma en que trabajo.
fuente
Estoy totalmente en desacuerdo con el concepto de que el Modelo no debe implementar el
INotifyPropertyChanged
. ¡Esta interfaz no es específica de la interfaz de usuario! Simplemente informa de un cambio. De hecho, WPF usa mucho esto para identificar cambios, pero eso no significa que sea una interfaz de UI. Lo compararía con el siguiente comentario: " Un neumático es un accesorio para el automóvil ". Claro que sí, pero las bicicletas, los autobuses, etc. también lo usan. En resumen, no tome esa interfaz como una cosa de UI.Dicho esto, no necesariamente significa que creo que el Modelo debería proporcionar notificaciones. De hecho, como regla general, el modelo no debe implementar esta interfaz, a menos que sea necesario. En la mayoría de los casos en los que no se envían datos del servidor a la aplicación cliente, el modelo puede quedar obsoleto. Pero si escucho los datos del mercado financiero, entonces no veo por qué el modelo no puede implementar la interfaz. Como ejemplo, ¿qué sucede si tengo una lógica que no es de UI, como un servicio que cuando recibe un precio de compra o venta por un valor determinado emite una alerta (por ejemplo, a través de un correo electrónico) o hace un pedido? Esta podría ser una posible solución limpia.
Sin embargo, hay diferentes formas de lograr las cosas, pero siempre argumentaría a favor de la simplicidad y evitaría la redundancia.
¿Qué es mejor? ¿Definir eventos en una colección o cambios de propiedad en el modelo de vista y propagarlo al modelo o hacer que la vista actualice intrínsecamente el modelo (a través del modelo de vista)?
El resultado final cada vez que ves a alguien que dice " no puedes hacer esto o aquello " es una señal de que no saben de qué están hablando.
Realmente depende de su caso y, de hecho, MVVM es un marco con muchos problemas y todavía no he visto una implementación común de MVVM en todos los ámbitos.
Desearía tener más tiempo para explicar los muchos sabores de MVVM y algunas soluciones a problemas comunes, en su mayoría proporcionados por otros desarrolladores, pero supongo que tendré que hacerlo en otro momento.
fuente
INotifyPropertyChanged
es parte delSystem.ComponentModel
espacio de nombres que es para el " comportamiento en tiempo de ejecución y tiempo de diseño de componentes y controles ". NO UTILICEINotifyPropertyChanged
en Modelos, solo en ViewModels. Enlace a documentos: docs.microsoft.com/en-us/dotnet/api/system.componentmodelEn MV-VM, ViewModel siempre (Modelo no siempre) implementa
INotifyPropertyChanged
Consulte la plantilla / kit de herramientas del proyecto MV-VM en http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspx . Utiliza el
DelegateCommand
comando y debe ser una excelente plantilla de inicio para sus proyectos MV-VM.fuente
Creo que MVVM tiene un nombre muy pobre y llamar al ViewModel un ViewModel hace que muchos pierdan una característica importante de una arquitectura bien diseñada, que es un DataController que controla los datos sin importar quién esté tratando de tocarlos.
Si piensa que el Modelo de vista es más como un DataController e implementa una arquitectura donde su DataController es el único elemento que toca los datos, entonces nunca tocaría los datos directamente, sino que siempre usaría el DataController. DataController es útil para la IU, pero no necesariamente solo para la IU. Es para la capa empresarial, la capa de interfaz de usuario, etc.
Terminas con un modelo como este. Incluso la empresa solo debe tocar los datos con ViewModel. Entonces tu enigma simplemente desaparece.
fuente
Depende de cómo hayas implementado tu modelo. Mi empresa utiliza objetos comerciales similares a los objetos CSLA de Lhotka y los utiliza ampliamente en
INotifyPropertyChanged
todo el modelo comercial.Nuestro motor de validación depende en gran medida de que se le notifique que las propiedades cambian a través de este mecanismo y funciona muy bien. Obviamente, si está utilizando una implementación diferente a la de los objetos comerciales donde la notificación de cambios no es tan crítica para la operación, puede tener otros métodos para detectar cambios en su modelo comercial.
También tenemos modelos de vista que propagan los cambios del modelo donde sea necesario, pero los modelos de vista están escuchando los cambios subyacentes del modelo.
fuente
Estoy de acuerdo con la respuesta de Paulo, la implementación
INotifyPropertyChanged
en Modelos es totalmente aceptable e incluso es sugerida por Microsoft:Aunque depende de usted decidir si desea ese tipo de implementación o no, pero recuerde:
Tomado de - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
He trabajado en algunos proyectos donde no hemos implementado
INotifyPropertyChanged
en nuestros modelos y debido a esto nos enfrentamos a muchos problemas; Se necesitaba una duplicación innecesaria de propiedades en VM y al mismo tiempo tuvimos que actualizar el objeto subyacente (con valores actualizados) antes de pasarlos a BL / DL.Enfrentará problemas especialmente si necesita trabajar con la colección de sus objetos modelo (digamos en una cuadrícula o lista editable) o modelos complejos; los objetos de modelo no se actualizarán automáticamente y tendrá que administrar todo eso en su VM.
fuente
Pero a veces (como en este texto de enlace de presentación ) el modelo es el servicio, que proporciona a la aplicación algunos datos en línea y luego debe notificar al empleador que llegaron nuevos datos o que los datos han cambiado usando eventos ...
fuente
Creo que la respuesta es bastante clara si desea adherirse a la MV-VM.
ver: http://msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx
En el patrón MVVM, la vista encapsula la interfaz de usuario y cualquier lógica de interfaz de usuario, el modelo de vista encapsula la lógica y el estado de presentación, y el modelo encapsula la lógica y los datos comerciales.
fuente
Yo diría en tu ViewModel. No es parte del modelo, ya que el modelo es independiente de la interfaz de usuario. El modelo debe ser 'todo, EXCEPTO agnóstico empresarial'
fuente
La implementación de INPC en los modelos se podría usar si los modelos se exponen claramente en ViewModel. Pero en general, ViewModel ajusta los modelos en sus propias clases para reducir la complejidad del modelo (que no debería ser útil para el enlace). En este caso, el INPC debe implementarse en ViewModel.
fuente
Estoy usando la
INotifyPropertyChange
interfaz en un modelo. En realidad, la UI o el cliente externo solo deben activar un cambio de propiedad del modelo.He notado varias ventajas y desventajas:
Ventajas
Notifier está en el modelo de negocio
Desventajas
El modelo tiene propiedades (qty, rate, comisión, totalfrieght). Totalfrieght se calcula utilizando cantidad, tasa, cambio de comisión.
En los valores de carga de db, el cálculo total de la longitud se llama 3 veces (cantidad, tasa, comisión). Debería ser una vez.
Si se asigna rate, qty en la capa empresarial, nuevamente se llama al notificador.
Debería haber una opción para deshabilitar esto, posiblemente en la clase base. Sin embargo, los desarrolladores podrían olvidarse de hacer esto.
fuente
Creo que todo depende del caso de uso.
Cuando tiene un modelo simple con muchas propiedades, puede hacer que implemente INPC. Por simple quiero decir que este modelo se parece bastante a un POCO .
Si su modelo es más complejo y vive en un dominio de modelo interactivo (modelos que hacen referencia a modelos, se suscriben a eventos de otros modelos), implementar eventos modelo como INPC es una pesadilla.
Póngase en una posición de alguna entidad modelo que tenga que colaborar con otros modelos. Tienes varios eventos para suscribirte. Todos ellos se implementan como INPC. Imagina esos controladores de eventos que tienes. Una enorme cascada de cláusulas if y / o clauss de cambio.
Otro problema con INPC. Debe diseñar sus aplicaciones para que se basen en la abstracción, no en la implementación. Esto se hace típicamente usando interfaces.
Echemos un vistazo a 2 implementaciones diferentes de la misma abstracción:
Ahora mira a los dos. ¿Qué te dice IConnectionManagerINPC? Que algunas de sus propiedades pueden cambiar. No sabes cuál de ellos. De hecho, el diseño es que solo IsConnected cambia, ya que el resto son de solo lectura.
Por el contrario, las intenciones de IConnectionManager son claras: "Puedo decirle que el valor de mi propiedad IsConnected puede cambiar".
fuente
Simplemente use el
INotifyPropertyChange
en su modelo de vista y no en el Modelo,el modelo generalmente usa el
IDataErrorInfo
para manejar los errores de validación, así que solo manténgase en su ViewModel y estará en su camino MVVM.fuente
Suponga que la referencia del objeto en su vista cambia. ¿Cómo notificará que todas las propiedades se actualicen para mostrar los valores correctos? Llamar
OnPropertyChanged
a su vista para todas las propiedades del objeto es una basura para mi punto de vista.Entonces, lo que hago es dejar que el objeto mismo notifique a alguien cuando cambia un valor en una propiedad, y en mi opinión, uso enlaces como
Object.Property1
,Object.Property2
y así sucesivamente . De esa manera, si solo quiero cambiar el objeto que se mantiene actualmente en mi vista, simplemente lo hagoOnPropertyChanged("Object")
.Para evitar cientos de notificaciones durante la carga de objetos, tengo un indicador booleano privado que lo configuré como verdadero durante la carga, que se verifica desde el objeto
OnPropertyChanged
y no hace nada.fuente
Normalmente ViewModel implementará el
INotifyPropertyChanged
. El modelo puede ser cualquier cosa (archivo xml, base de datos o incluso objeto). El modelo se usa para dar los datos al modelo de vista, que se propaga a la vista.mira aquí
fuente
En mi opinión, creo que el modelo de vista implementa
INotifyPropertyChange
y el modelo podría utilizar la notificación en un "nivel" diferente.por ejemplo, con algún servicio de documentos y un objeto de documento, tiene un evento documentChanged que un modelo de vista escucha para borrar y reconstruir la vista. En el modelo de vista de edición, tiene un cambio de propiedad para las propiedades del documento para admitir las vistas. Si el servicio hace mucho con el documento al guardar (fecha de cambio de actualización, último usuario, etc.), es fácil obtener una sobrecarga de eventos cambiados de propiedad y solo un cambio de documento es suficiente.
Pero si lo usa
INotifyPropertyChange
en su modelo, creo que es una buena práctica transmitirlo en su modelo de vista en lugar de suscribirse directamente en su vista. En ese caso, cuando los eventos cambian en su modelo, solo tiene que cambiar el modelo de vista y la vista permanece intacta.fuente
Todas las propiedades, que están vinculadas a mi vista, están en mi ViewModel (s). Por lo tanto, deberían implementar la interfaz INotifyPropertyChanged. Por lo tanto, la Vista obtiene todos los cambios.
[Utilizando el kit de herramientas MVVM Light, los dejo heredar de ViewModelBase.]
El modelo tiene la lógica de negocios, pero no tiene nada que ver con la vista. Por lo tanto, no hay necesidad de la interfaz INotifyPropertyChanged.
fuente