Как синхронизировать коллекции моделей и моделей - PullRequest
9 голосов
/ 26 января 2010

Я использую сетку данных wpf toolkit для отображения наблюдаемой коллекции AccountViewModels.

Дело в том, что когда я удаляю учетную запись из сетки, я хочу, чтобы она была удалена из ObservableCollection - чтобы дать пользователю визуальную обратную связь, но я хочу, чтобы базовый список моделей учетных записей оставался прежним, только с IsDeleted. флаг установлен на модели учетной записи.

Тогда, когда изменения фиксируются, моя служба знает, какие учетные записи добавить / обновить или удалить в базе данных.

Я подписываюсь на событие CollectionChanged:

AccountViewModels.CollectionChanged += AccountsChanged;

и затем установка флага модели модели isdeleted в true при каждом удалении:

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

но, очевидно, это затем удаляет его из наблюдаемой коллекции. Поэтому, когда я приду к фиксации изменений, не будет никаких учетных записей с установленным флагом IsDeleted. то есть они будут уже удалены.

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

        }

Значит ли это, что мне нужно вести два списка, один список моделей учетных записей, а другой - наблюдаемый набор моделей accountview? Это только кажется неприятным, и должен быть лучший способ сделать это.

Ответы [ 2 ]

3 голосов
/ 02 марта 2010
3 голосов
/ 26 января 2010

Я не думаю, что вы можете сделать это лучше с ObservableCollection, так как этот класс содержит свой собственный внутренний список объектов.

Однако, если вы реализуете собственную коллекцию, которая реализует INotifyCollectionChanged и INotifyPropertyChanged, вы можете позволить ей обернуть и отфильтровать вашу исходную коллекцию.

Он может фильтровать флаг IsDeleted, чтобы они не были видны.

Каждый раз, когда пользователь удаляет элемент, вы можете напрямую изменить модель домена, установив для флага IsDeleted значение true. Однако вам все еще понадобится механизм обработки событий, чтобы иметь возможность вызывать соответствующие события, но при таком подходе у вас будет только один набор элементов.

Пользовательская коллекция будет просто проекцией на модель предметной области с добавленными событиями.

...