Estoy buscando algunos consejos sobre cómo resolver un problema que nos está molestando en este momento.¿Cómo actualizar modelos de vista anidados de MVVM cuando el modelo cambia y viceversa?
Digamos que tenemos un par de objetos de negocio (POÇOS) como
public class UserGroup
{
public virtual ICollection<Person> People { get; set; }
}
public class Person
{
public virtual ICollection<Adress> Adresses { get; set; }
}
public class Adress
{
public virtual string StreetName { get; set; }
}
Esto es un poco simplista, pero espero que sea suficiente para que se entiende la idea. UserGroup tiene una colección de persona casos y cada persona ejemplo, tiene una colección de Dirección casos.
El modelo de vista para el UserGroup POCO podría tener este aspecto:
public class UserGroupViewModel
{
private UserGroup userGroupModel;
public UserGroup UserGroupModel
{
get { return this.userGroupModel; }
set
{
this.userGroupModel = value;
this.PeopleViewModelCollection =
new ObservableCollection<PeopleViewModel>();
foreach (Person p in this.UserGroupModel.People)
{
var personViewModel = new PersonViewModel();
personViewModel.PersonModel = p;
this.PeopleViewModelCollection.Add(personViewModel);
}
}
}
public ObservableCollection<PersonViewModel> PersonViewModelCollection
{
get;
set;
}
}
Donde como el modelo de vista para el persona POCO podría tener este aspecto:
public class PersonViewModel
{
private Person personModel;
public Person PersonModel
{
get { return this.personModel; }
set
{
this.personModel = value;
this.AddressViewModelCollection =
new ObservableCollection<AddressViewModel>();
foreach (Address a in this.PersonModel.Adresses)
{
var addressViewModel = new AddressViewModel();
addressViewModel.AddressModel = a;
this.AdressViewModelCollection.Add(addressViewModel);
}
}
}
public ObservableCollection<AddressViewModel> AddressViewModelCollection
{
get;
set;
}
}
vez más es demasiado simplista, pero lo que quiero mostrar es que ViewModels tiene ObserableCollections de otros ViewModels anidados dentro de ellos.
El colocador de la propiedad del modelo respectivo, p. PersonViewModel.PersonModel
crea ViewModels para todas las direcciones del Person
y las agrega a la propiedad ObservableCollection<AdressViewModels> AdressViewModelCollection
del PersonViewModel
.
En este punto podríamos utilizar este código para mostrar estos ViewModels en una vista. Podemos, por ejemplo, muestre el StreetName
de Person
's Adress
.
¿Qué debe hacer ahora cuando elimina un Adress
de un Person
? La eliminación de AdressViewModel
del PersonViewModel.AdressViewModelCollection
actualizará la GUI, pero en realidad no permite actualizar los modelos subyacentes.
similar a que si se agrega otro Adress
a un modelo Person
los ViewModels existentes no van a reflejar este cambio ya que la única PersonViewModel.AdressViewModelCollection
sería reconstruida vez que la propiedad PersonViewModel.PersonModel
se ajusta de nuevo.
¿Existe una forma (preferiblemente fácil) de lograr esta actualización bidireccional entre ViewModel y Model? ¿O tal vez esto no es aconsejable y es mejor manejar este problema de una manera completamente diferente?
¡Tengo muchas ganas de escuchar opiniones diferentes sobre este problema!
EDIT: me gustaría afirmar que nuestras clases del modelo se generan por el Entity Framework 4.0 y son POCOs (véase el ejemplo de los objetos de negocio más arriba). No estoy seguro si eso fue lo suficientemente claro en la pregunta en sí. Nos gustaría exponer las propiedades de navegación (por ejemplo, Person.Addresses
) como ICollection<T>
.
Gracias por su respuesta. He editado la pregunta para aclarar el origen de nuestros modelos. Son POCO y son generados por EF. Mientras que la VM podría (o posiblemente debería) tener un 'ObservableCollection', la clase del modelo tendrá una 'ICollection ' por lo tanto, la sincronización solo funcionaría desde el ViewModel hasta el Model, ¿es correcto? –