2011-02-02 7 views
5

Sto cercando alcuni consigli su come risolvere un problema che ci sta infastidendo al momento.Come aggiornare ViewModels nidificati MVVM quando Model cambia e viceversa?

Diciamo che abbiamo un paio di oggetti di business (pocos) come

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; } 
} 

Questo è un po 'semplicistico, ma spero che sia abbastanza in modo che si ottiene l'idea. UserGroup ha una collezione di persona casi e ogni persona esempio ha una collezione di Indirizzo istanze.

Il ViewModel per la UserGroup POCO potrebbe assomigliare a questo:

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; 
    } 
} 

Dove come il ViewModel per la persona POCO potrebbe assomigliare a questo:

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; 
    } 
} 

Anche in questo caso è eccessivamente semplicistico ma quello che voglio mostrare è che ViewModels ha ObserableCollections di altri ViewModels annidati al loro interno.

Il setter della rispettiva proprietà del modello, ad es. PersonViewModel.PersonModel crea ViewModels per tutti gli indirizzi di Person e li aggiunge alla proprietà ObservableCollection<AdressViewModels> AdressViewModelCollection di PersonViewModel.

A questo punto è possibile utilizzare questo codice per visualizzare questi ViewModels in una vista. Possiamo ad es. visualizza lo StreetName di uno AdressPerson.

Ora cosa si deve fare quando si elimina uno Adress di un Person? La rimozione dello PersonViewModel.AdressViewModelCollection dal PersonViewModel.AdressViewModelCollection aggiornerà la GUI ma in realtà non consente di aggiornare i modelli sottostanti.

Simile a che se si aggiunge un altro Adress ad un modello Person i ViewModels esistenti non sono in corso per riflettere tale cambiamento dal momento che il PersonViewModel.AdressViewModelCollection sarebbe stato ricostruito solo una volta la proprietà PersonViewModel.PersonModel è impostata di nuovo.

C'è un modo (preferibilmente facile) per ottenere questo aggiornamento a due vie tra ViewModel e Model? O forse questo non è consigliabile ed è meglio gestire questo problema in un modo completamente diverso?

Sono ansioso di sentire opinioni diverse su questo problema!

EDIT: Vorrei affermare che le nostre classi del modello sono generati dal Entity Framework 4.0 e sono pocos (vedi esempio di oggetti di business sopra). Non sono sicuro se ciò fosse abbastanza chiaro nella domanda stessa. Vorremmo esporre le proprietà di navigazione (ad esempio Person.Addresses) come ICollection<T>.

risposta

0

Sembra che non sia la cascata il problema. È la sincronizzazione tra il modello e il modello di visualizzazione.

Avrete bisogno di ascoltare l'evento collectionchanged delle collezioni osservabili e un'implementazione è fornita here.

Penso che la tua unica opzione sia implementare la proprietà INotifyPropertyChanged nel tuo modello poiché il framework di entità non fornisce un modo per aggiornare ViewModel.

+0

Grazie per la risposta. Ho modificato la domanda per chiarire l'origine dei nostri modelli. Sono POCO e generati dall'EF. Mentre la VM potrebbe (o forse dovrebbe) avere un 'ObservableCollection ' la classe del modello stessa avrà un 'ICollection ' quindi la sincronizzazione funzionerebbe solo dal ViewModel al Modello, è corretta? –

1

È possibile semplificare le cose utilizzando i proxy dinamici (ad esempio Castle.Proxy), dare un'occhiata a questo post per un'idea su come ottenere ciò.

Problemi correlati