2009-03-13 11 views
5

Hay muchos ejemplos excelentes en MVVM, pero todavía estoy confundido.Silverlight MVVM modelo de enlace y vista modelo

Digamos que tiene un modelo de cliente y un modelo de vista de cliente. Parece que habría una propiedad Name en CustomerModel y otra en CustomerViewModel. El colocador en CustomerViewModel configurará la propiedad Name del CustomerModel y luego llamará a OnPropertyChanged (PropName) para que la UI se actualice. ¿Es esto realmente correcto? Parece que el getter/setters se definirá dos veces. Si tienes un modelo con 50 propiedades, entonces te resultará muy tedioso.

Además, digamos que establecí una propiedad Qty. ViewModel actualiza el modelo. El Modelo actualiza su propiedad de Valor en función de la nueva Cantidad. ¿Cómo se notifica a ViewModel que la propiedad del Modelo ha cambiado?

Respuesta

2

En el ejemplo del cliente que usted proporciona, CustomerModel contiene toda la información que almacena su base de datos (u otro servidor). El CustomerViewModel contiene información similar si se mostrará en la UI (Nombre, etc., potencialmente otras 50 propiedades si tiene una clase grande) pero utiliza la interfaz INotifyPropertyChanged para mostrarlas como propiedades que la Vista (es decir, el XAML) puede unirse a.

p. Ej.

public int Name 
{ 
    get 
    { 
     return this.name; 
    } 

    set 
    { 
     if (this.name!= value) 
     { 
      this.name= value; 
      this.OnPropertyChanged("Name"); 
     } 
    } 
} 

El modelo de vista también contiene otros bits de estado de la interfaz de usuario - banderas visibilidad, índice de pestaña actual, los bits más complejas de texto construido a partir de los datos en varios campos, ObservableCollection < > de elementos secundarios, etc. Todo está allí para estar obligado a la XAML.

He visto el ViewModel creado a partir del Modelo como un proceso único de una sola dirección, p. Ej. con un constructor:

CustomerViewModel viewModel = new CustomerViewModel(customer); 

o como un método de extensión

CustomerViewModel viewModel = customer.ToViewModel(); 

no he visto ninguna provisión para la actualización de un modelo de vista de los cambios en el modelo - el punto del modelo de vista es que está aislado de el modelo. Guarda una copia separada de los datos. No propaga los cambios al modelo, no hasta que presione el botón "guardar". Entonces, si cancela, nada en el modelo ha cambiado y no hay nada que deshacer.

Puede que esté intentando demasiado para mantener el ViewModel actualizado con el modelo; en la mayoría de los casos, como guardar o cargar, puede deshacerse del modelo de vista actual y crear uno nuevo a partir del estado actual del modelo. ¿Necesita mantener el estado de la interfaz de usuario de ViewModel y cambiar los datos en él? No es un requisito común, pero se puede hacer con un método o dos cuando se produce el guardado o la carga.

Así que también existe la suposición de que esta lógica de cableado ocurre en alguna parte. Esta es la razón por la que la mayoría de los patrones que involucran views también involucran a los controladores que son responsables de actuar sobre los comandos (por ejemplo, mostrar un cliente, guardar un cliente) y configurar el nuevo estado de UI después.

+0

Si mantiene ViewModel separado del modelo, ¿cómo se aplican las reglas en el modelo? Digamos que tengo un modelo con cantidad y valor. Si cambio el Qty en el ViewModel que debe fluir al modelo que actualiza el valor basado en el nuevo Qty. Ahora el ViewModel debería mostrar el nuevo valor. –

+0

"Si cambio el Qty en el ViewModel que debe pasar al modelo" no, no hasta que presione un botón Guardar o similar. Cuando lo haga, el controlador debe actualizar el modelo, persistir y crear un nuevo ViewModel fuera del nuevo estado del modelo. – Anthony

+0

Entonces, si no fluye hacia el Modelo, ¿cómo obtiene ViewModel un campo de Valor actualizado? Si cambio el Qty, como usuario esperaría ver el nuevo valor. El MV no tiene la lógica comercial para calcular el Valor, solo el Modelo lo hace. –

5

Su ViewModel no tiene que encapsular estrictamente el modelo. En su escenario, CustomerViewModel podría tener una propiedad de Cliente, que al final significa que su Vista se vincula a las propiedades del Modelo ... simplemente lo hace a través de ViewModel. Eso es perfectamente legítimo. Dicho esto, sin embargo, a menudo hay un beneficio al encapsular esto. Su modelo de negocio no puede incluir notificación de cambio. Es posible que no desee que la interacción del usuario modifique el modelo comercial hasta que el usuario haga clic en un botón Aceptar.Su modelo de negocio puede a través de excepciones para malas entradas, mientras que usted desea usar otra forma de validación. Estoy seguro de que puedes pensar en otras cosas. De hecho, supongo que la mayor parte del tiempo querrás la encapsulación, por lo que no es realmente "tedioso" en el sentido de simplemente escribir muchos métodos de retransmisión sin sentido.

0

Exactamente cómo se hace esto, dependerá en parte de su modelo de negocio como ya ha indicado wekempf.

Dependiendo de cómo muestre la información del cliente en su UI, es posible que tenga un ObservableCollection de cliente (su modelo) en su ViewModel. Si, por ejemplo, está mostrando un escenario maestro/detalle, donde puede tener una lista de clientes y mostrar los detalles a continuación cuando se selecciona un cliente en particular.

Cuestiones relacionadas