2010-01-26 7 views
9

Ich verwende das WPF-Toolkit-Datagrid, um eine beobachtbare Sammlung von AccountViewModels anzuzeigen.Wie Sammlungen von Ansichtsmodellen und Modellen synchron gehalten werden

Die Sache ist, wenn ich ein Konto aus dem Raster löschen, ich möchte es aus der ObservableCollection entfernt - um dem Benutzer visuelles Feedback zu geben, aber ich möchte die zugrunde liegende Liste von Account-Modellen gleich bleiben, nur mit einem 'IsDeleted 'Flag im Account-Modell gesetzt.

Dann weiß mein Dienst, wann die Änderungen festgeschrieben werden, welche Konten hinzugefügt/aktualisiert oder in der Datenbank gelöscht werden.

Im zeichn zur Collection Veranstaltung:

AccountViewModels.CollectionChanged += AccountsChanged; 

und dann die Viewmodel Modell isDeleted Flag auf true setzen, wenn etwas entfernt wird:

private void AccountsChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.NewItems != null) 
     { 
      foreach (AccountViewModel model in e.NewItems) 
      { 
       model.PropertyChanged += accountPropertyChanged; 
       model.Account.IsNew = true; 
      } 
     } 
     if (e.OldItems != null) 
     { 

      foreach (AccountViewModel model in e.OldItems) 
      { 
       model.PropertyChanged -= accountPropertyChanged; 
       model.Account.IsDeleted = true; 
      } 
     } 
    } 

aber offensichtlich diese entfernt dann aus dem beobachtbaren Sammlung. Wenn ich also die Änderungen beginne, wird es keine Konten mit IsDeleted-Flag geben. d.h. sie sind bereits entfernt worden.

foreach (AccountViewModel acc in m_ViewModel.AccountViewModels) 
     { 
      WorkItem workItem = null; 
      if(acc.Account.IsNew) 
       workItem = new WorkItem("Saving new account: " + acc.AccountName, "Saving new account to the database",() => Service.AddAccount(acc.Account)); 
      else if (acc.Account.IsDeleted) 
       workItem = new WorkItem("Removing account: " + acc.AccountName, "Setting account inactive in the database",() => Service.RemoveAccount(acc.Account)); 
      else if(acc.Account.IsDirty) 
       workItem = new WorkItem("Updating account: " + acc.AccountName, "Updating account in the database",() => Service.UpdateAccount(acc.Account)); 

      workItems.Add(workItem); 

     } 

So bedeutet das ich zwei Listen pflegen müssen, eine Liste der Kontomodelle und die andere eine beobachtbare Sammlung von accountviewmodels? Dies scheint nur böse und es muss einen besseren Weg geben, dies zu tun.

Antwort

3

Ich denke nicht, dass Sie dies mit ObservableCollection besser machen können, da diese Klasse eine eigene interne Liste von Objekten enthält.

Wenn Sie jedoch eine benutzerdefinierte Sammlung implementieren, die INotifyCollectionChanged und INotifyPropertyChanged implementiert, können Sie die Quellensammlung umbrechen und filtern.

Es könnte auf dem IsDeleted Flag filtern, so dass diese nicht sichtbar sind.

Wenn ein Benutzer ein Element entfernt, können Sie das Domänenmodell direkt ändern, indem Sie das Flag IsDeleted auf true setzen. Sie benötigen jedoch weiterhin einen Mechanismus, um die entsprechenden Ereignisse auszulösen, aber mit diesem Ansatz haben Sie nur eine einzige Sammlung von Elementen.

Die benutzerdefinierte Sammlung wäre einfach eine Projektion über das Domänenmodell mit zusätzlichen Ereignissen.

+0

Wenn ich diesen Weg zu gehen, wie ich die Eigenschaft geänderte Ereignis erfasse, wenn eines der Felder in meinem Modell im Netz bearbeitet wird. Ich möchte nicht wirklich, dass mein Domain-Modell INotifyPropertyChanged implementieren muss, das ist etwas, was mein View-Modell zuvor gemacht hat. – cjroebuck

+0

Das habe ich gemeint, als ich sagte, dass man * einen * Vielseitigkeitsmechanismus brauchen sollte. Entweder Sie können ein Ereignis von Ihrem Domänenmodell auslösen (es muss nicht INotifiedPropertyChanged sein - es könnte stattdessen ein benutzerdefiniertes Ereignis sein), oder Sie müssen die projizierende Sammlung explizit über die Änderung benachrichtigen, damit sie die richtigen Ereignisse auslösen kann. Eine dritte Option ist, dass die Projektionssammlung nach Änderungen im zugrundeliegenden Modell fragt, aber diese Route ist voller Gefahren ... –

Verwandte Themen