viewmodelbase stacklayout instancelocator ejemplo data content calculated bindingcontext c# mvvm

c# - instancelocator - xamarin stacklayout content binding



MVVM-¿PropertyChanged en Model o ViewModel? (7)

Aunque generalmente estoy a favor de un modelo que implementa INPC, la llamada para INPC en un modelo de vista compuesto es cuando expone las propiedades inferidas que son vinculables a la vista. OMI, ya que INPC está integrado en System.dll, un modelo que lo implementa puede considerarse POCO. Para las colecciones hay un beneficio de rendimiento del modelo basado en INPC. En una plataforma de 64 bits, una VM envoltura tendría un multiplicador de 8 factores en el tamaño del byte (cargar la extensión del depurador SOS para el tamaño real) de ObservableCollection <ViewModel> en comparación con ObservableCollection <Model>.

He pasado por algunos tutoriales MVVM y he visto esto hecho de ambas maneras. La mayoría usa el ViewModel para PropertyChanged (que es lo que he estado haciendo), pero encontré uno que hizo esto en el Modelo. ¿Ambos métodos son aceptables? Si es así, ¿cuáles son los beneficios / inconvenientes de los diferentes métodos?


Como regla general, cualquier objeto al que se vinculará (incluso si no necesita un enlace bidireccional y una notificación de cambio de propiedad), debe implementar INotifyPropertyChanged . Esto se debe a que no hacerlo puede causar pérdidas de memoria


El creador de MVVM, JohnGossman, afirma en this artículo del blog (mencionado por @Jonathan Allen) que:

En ejemplos simples, la Vista es datos enlazados directamente al Modelo. Las partes del modelo simplemente se muestran en la vista mediante un enlace de datos unidireccional. Otras partes del modelo se pueden editar vinculando directamente los controles de dos vías a los datos. Por ejemplo, un booleano en el Modelo puede estar vinculado a un CheckBox o un campo de cadena a un TextBox.

Sin embargo, en la práctica, solo un pequeño subconjunto de la interfaz de usuario de la aplicación puede vincularse directamente al Modelo, especialmente si el Modelo es una clase preexistente o un esquema de datos sobre el cual el desarrollador de la aplicación no tiene control.

Prefiero seguir las prácticas que siguen siendo aplicables cuando la aplicación escala. Si "en la práctica [...], solo un pequeño subconjunto de la interfaz de usuario de la aplicación puede vincularse directamente al modelo", no parece ser una buena práctica, ya que no planeo abordar solo "simple casos "o" un pequeño subconjunto de la interfaz de usuario de la aplicación ".
Para "casos simples" para empezar, ni siquiera estaría usando MVVM.


Estaría absolutamente de acuerdo con Jonathan Allen.

Si no tiene nada que agregar a su ''Modelo de visualización'' (Comandos, propiedades específicas de la vista que afectan a la presentación, etc.), definitivamente implementaría INotifyPropertyChanged en el modelo y lo expondría directamente (si puede, el ''modelo'' puede que no soy tuyo). No solo terminas repitiendo una gran cantidad de código repetitivo, mantener los dos sincronizados es un dolor absoluto.

INotifyPropertyChanged no es una interfaz específica de vista, solo hace exactamente lo que sugiere su nombre: genera un evento cuando cambia una propiedad. WinForms, WPF y Silverlight simplemente lo apoyan para Binding. ¡Ciertamente lo he usado para propósitos de no presentación!


INotifyPropertyChanged debe ser implementado por todos los tipos que consume la vista (a menos que solo tenga valores constantes, por supuesto).

¿Devuelves modelos (no modelos de vista) a una vista? Si es así, entonces debería implementar INotifyPropertyChanged.


Los patrones y prácticas de Microsoft, el inventor de MVVM, y todos estamos en desacuerdo con la respuesta elegida.

Normalmente, el modelo implementa las facilidades que facilitan el enlace a la vista. Por lo general, esto significa que admite la notificación de cambios de propiedad y colección a través de las interfaces INotifyPropertyChanged e INotifyCollectionChanged. Las clases de modelos que representan colecciones de objetos típicamente derivan de la clase ObservableCollection, que proporciona una implementación de la interfaz INotifyCollectionChanged.

- Patrones y prácticas de Microsoft: http://msdn.microsoft.com/en-us/library/gg405484%28v=pandp.40%29.aspx#sec4

En este punto, el enlace de datos entra en juego. En ejemplos simples, la Vista es datos enlazados directamente al Modelo. Las partes del modelo simplemente se muestran en la vista mediante un enlace de datos unidireccional. Otras partes del modelo se pueden editar vinculando directamente los controles de dos vías a los datos. Por ejemplo, un booleano en el Modelo puede estar vinculado a un CheckBox o un campo de cadena a un TextBox.

- John Gossman, inventor de MVVM: http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx

Mi propio artículo: http://www.infoq.com/articles/View-Model-Definition

Es un antipatrón tener un "modelo de vista" que simplemente ajusta un modelo y expone la misma lista de propiedades. El trabajo del modelo de vista es llamar a los servicios externos y exponer las colecciones individuales y de modelos que esos servicios devuelven.

Razones:

  1. Si el modelo se actualiza directamente, el modelo de vista no sabrá cómo activar un evento de propiedad modificada. Esto hace que la interfaz de usuario se desincronice.
  2. Esto limita severamente sus opciones para enviar mensajes entre los modelos de vista padre e hijo.
  3. Si el modelo tiene su propia notificación de cambio de propiedad, # 1 y 2 no son un problema. En su lugar, debe preocuparse por las fugas de memoria si la VM del wrapper queda fuera del alcance pero el modelo no.
  4. Si sus modelos son complejos, con muchos objetos para niños, entonces tendrá que caminar por todo el árbol y crear un segundo gráfico de objetos que sombree el primero. Esto puede ser bastante tedioso y propenso a errores.
  5. Las colecciones envueltas son particularmente difíciles de trabajar. Cada vez que algo (UI o backend) inserta o elimina un elemento de una colección, la colección sombra debe actualizarse para que coincida. Este tipo de código es muy difícil de entender.

Eso no quiere decir que nunca necesitará un modelo de vista que envuelva un modelo. Si su modelo de vista expone propiedades que son significativamente diferentes del modelo y no se pueden empastar con un IValueConverter, entonces tiene sentido un modelo de vista envolvente.

Otra razón por la que puede necesitar un modelo de vista de ajuste es que sus clases de datos no admiten el enlace de datos por algún motivo. Pero incluso entonces, por lo general, es mejor crear un modelo normal, enlazable y copiar los datos de las clases de datos originales.

Y, por supuesto, su modelo de vista tendrá propiedades específicas de la interfaz de usuario, como el elemento de una colección actualmente seleccionado.


La INotifyPropertyChanged (INPC) se utiliza para Binding .

Entonces, en el caso promedio, desea implementarlo en su ViewModel .

El ViewModel se usa para desacoplar el Model de su View , por lo que no es necesario tener un INPC en su Model , ya que no desea Bindings a su Model .

En la mayoría de los casos, incluso para propiedades más pequeñas, todavía tiene un ViewModel muy pequeño.

Si desea una base sólida para MVVM , probablemente vaya a usar algún tipo de MVVM Framework como caliburn.micro . Su uso le dará un ViewModelBase (o aquí NotifyPropertyChangedBase ) para que usted no tenga que implementar esos miembros de la interfaz y solo pueda usar NotifyOfPropertyChange(() => MyProperty) , que es mucho más fácil y menos propenso a errores.

ACTUALIZACIÓN Como parece que hay muchos desarrolladores de Windows Forms por ahí, aquí hay un excelente artículo que brindará una comprensión más profunda de lo que trata MVVM: MSDN Magazine en MVVM

He vinculado especialmente la parte sobre el datamodel, que trata la pregunta.