2010-01-26 15 views
9

Używam zestawu datagrid toolkit wpf do wyświetlania obserwowalnej kolekcji AccountViewModels.Jak przechowywać kolekcje modeli widoków i modeli zsynchronizowanych

Chodzi o to, kiedy usuwam konto z sieci, chcę je usunąć z ObservableCollection - aby przekazać użytkownikowi wizualną informację zwrotną, ale chcę, aby podstawowa lista modeli Konta pozostała taka sama, tylko za pomocą "IsDeleted" "flaga ustawiona w modelu konta.

Następnie, gdy zmiany zostaną zatwierdzone, moja usługa wie, które konta dodać/zaktualizować lub usunąć w bazie danych.

Im zapisanie się na razie CollectionChanged:

AccountViewModels.CollectionChanged += AccountsChanged; 

a następnie ustawienie modelu isdeleted banderę ViewModels' true, gdy coś jest usuwany:

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

ale oczywiście to następnie usuwa go z obserwowalne kolekcja. Więc kiedy przyjdę do zatwierdzenia zmian, nie będzie kont z ustawioną flagą IsDeleted. to znaczy, że zostaną już usunięte.

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

     } 

Więc to oznacza, że ​​trzeba utrzymać dwie listy, jedna lista modeli rachunku i inne zauważalnego kolekcję accountviewmodels? To wydaje się paskudne i musi być lepszy sposób na zrobienie tego.

Odpowiedz

3

Nie sądzę, że można to zrobić lepiej dzięki ObservableCollection, ponieważ ta klasa posiada własną wewnętrzną listę obiektów.

Jednakże, jeśli zaimplementujesz niestandardową kolekcję, która implementuje INotifyCollectionChanged i INotifyPropertyChanged, możesz pozwolić jej owijać i filtrować kolekcję źródłową.

Może filtrować na flagę IsDeleted, aby nie były widoczne.

Za każdym razem, gdy użytkownik usunie przedmiot, można bezpośrednio zmodyfikować model domeny, ustawiając flagę IsDeleted na wartość true. Jednak nadal będziesz potrzebował mechanizmu uaktywniania, aby móc podnosić odpowiednie zdarzenia, ale przy takim podejściu masz tylko jedną kolekcję przedmiotów.

Niestandardowa kolekcja to po prostu rzutowanie na model domeny z dodanymi zdarzeniami.

+0

Jeśli pójdę tą drogą, jak mogę uchwycić właściwości zmieniono zdarzenia, gdy jedno z pól w moim modelu jest edytowane w siatce. Naprawdę nie chcę, aby mój model domeny musiał implementować INotifyPropertyChanged, to jest coś, co mój wcześniejszy model robił wcześniej. – cjroebuck

+0

To właśnie miałem na myśli, gdy powiedziałem, że musisz mieć * jakiś * mechanizm wrażeń w miejscu. Możesz podnieść zdarzenie z modelu domeny (nie musi to być INotifiedPropertyChanged - może to być zdarzenie niestandardowe), lub musisz jawnie powiadomić kolekcję wyświetlającą o zmianie, aby mogła podnieść prawidłowe zdarzenia. Trzecią opcją jest zbieranie danych z Projektu w celu wprowadzenia zmian w modelu bazowym, ale ta trasa jest obarczona niebezpieczeństwem ... –

Powiązane problemy