如何保持视图模型和模型的集合同步

cjr*_*uck 9 wpf observablecollection viewmodel

我正在使用wpf工具包datagrid来显示AccountViewModel的可观察集合.

问题是当我从网格中删除一个帐户时,我希望它从ObservableCollection中删除 - 给用户提供视觉反馈,但我希望帐户模型的基础列表保持不变,只需设置'IsDeleted'标志帐户模型.

然后,无论何时提交更改,我的服务都知道在数据库中添加/更新或删除哪些帐户.

我订阅了CollectionChanged事件:

AccountViewModels.CollectionChanged += AccountsChanged;
Run Code Online (Sandbox Code Playgroud)

然后在删除某些内容时将viewmodels的model 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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

但显然这会从可观察的集合中删除它.因此,当我提交更改时,将不会设置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);

        }
Run Code Online (Sandbox Code Playgroud)

这是否意味着我需要维护两个列表,一个是帐户模型列表,另一个是可观察的accountviewmodel集合?这看起来很讨厌,必须有一个更好的方法来做到这一点.

Mar*_*ann 4

我认为使用 ObservableCollection 无法做得更好,因为该类拥有自己的内部对象列表。

但是,如果您实现一个实现 INotifyCollectionChanged 和 INotifyPropertyChanged 的​​自定义 Collection,则可以让它包装和过滤您的源集合。

它可以过滤 IsDeleted 标志,以便这些不可见。

每当用户删除项目时,您都可以直接修改域模型,将 IsDeleted 标志设置为 true。但是,您仍然需要一个事件机制来引发适当的事件,但使用这种方法,您只有一个项目集合。

自定义集合只是域模型上的投影,并添加了事件。