2011-02-02 17 views
5

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>.

Respuesta

0

Parece que el problema no es la cascada. Es la sincronización entre el modelo y el modelo de vista.

Tendrá que escuchar el evento de recolección de colecciones observables y se proporciona una implementación here.

Creo que su única opción es implementar INotifyPropertyChanged en su modelo ya que el marco de entidad no proporciona una manera de actualizar su ViewModel.

+0

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? –

1

Puede simplificar las cosas con proxies dinámicos (por ejemplo, Castle.Proxy), eche un vistazo a este post para tener una idea de cómo lograr esto.

Cuestiones relacionadas