Siéntete libre de divulgar nuestra página y códigos con tus amigos, danos de tu ayuda para hacer crecer esta comunidad.
Solución:
Cuando la vista se vincula directamente con el modelo (que también es el caso cuando ViewModel expone el modelo), está mezclando código de interfaz de usuario y código de datos. El objetivo de MVVM es separar estos dos dominios de código. Para eso está el ViewModel.
El modelo de vista debe tener sus propias propiedades a las que la vista se puede enlazar. Un ejemplo:
class PersonViewModel
private Person OriginalModel get; set;
public ValueViewModel Name get; set;
public ValueViewModel Postcode get; set;
protected void ReadFromModel(Person person)
OriginalModel = person;
Name.Value = OriginalModel.Name;
Postcode.Value = OriginalModel.Postcode;
protected Person WriteToModel()
OriginalModel.Name = Name.Value; //...
return OriginalModel;
El uso de un diseño ViewModel de este tipo realmente separa sus objetos de datos de su código de interfaz de usuario. Cuando se cambia la estructura de la clase Person, la interfaz de usuario no necesita ajustarse en consecuencia, porque ViewModel los separa entre sí.
Ahora a tu pregunta. Como puede ver en el ejemplo anterior, utilicé un genérico ValueViewModel
. Esta clase implementa INotifyPropertyChanged
(y algunas otras cosas). Cuando recibes un nuevo Person
ejemplo, solo tienes que llamar ReadFromModel(newPerson)
en su ViewModel para actualizar la interfaz de usuario, porque los ValueViewModels a los que se vincula la vista informarán a la interfaz de usuario cuando cambie su valor.
Aquí un ejemplo extremadamente simplificado de la estructura interna del ValueViewModel
:
class ValueViewModel : INotifyPropertyChanged
private T _value;
public T Value
get return _value;
set
_value = value;
RaisePropertyChanged("Value");
Este es un enfoque que usamos en nuestra biblioteca MVVM. Tiene la ventaja de que obliga al desarrollador a separar claramente el código de las preocupaciones de los diseñadores. Y, como efecto secundario, genera un diseño de código estandarizado en todas sus vistas y modelos de vista y, por lo tanto, mejora la calidad del código.
Si la vista se vincula directamente con el modelo, siempre que el servicio utilice la misma instancia, cualquier cambio en las propiedades del modelo se propagará a la vista.
Sin embargo, si está recreando un nuevo modelo en el servicio, le dará al modelo de vista el nuevo modelo. Espero ver el modelo como una propiedad en el modelo de vista, por lo que cuando configura esa propiedad, todos los enlaces deben recibir una alerta del cambio.
//in the ViewModel
public Person Model
get return _person;
set _person = value;
RaisePropertyChanged("Model"); //<- this should tell the view to update
EDITAR:
Ya que dices que hay específicos ViewModel
lógica, entonces puede adaptar esas propiedades en el ViewModel
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
if(e.PropertyName == "Prop1") RaisePropertyChanged("SpecicalProperty");
...
public string SpecicalProperty
get
reutrn Model.Prop1 + " some additional logic for the view";
EN XAML
De esta manera solo los dos Model
y ViewModel
las propiedades están vinculadas a la vista sin duplicar los datos.
Puede volverse más elegante creando un asistente para vincular los cambios de propiedad del modelo al modelo de vista o usar un diccionario de mapeo
_mapping.Add("Prop1", new string[] "SpecicalProperty", "SpecicalProperty2" );
y luego encuentre las propiedades para actualizar obteniendo la lista de propiedades
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
string[] props;
if(_mapping.TryGetValue(e.PropertyName, out props))
foreach(var prop in props)
RaisePropertyChanged(prop);