【问题标题】:MVVM: Handling logical child objects of models in collectionsMVVM:处理集合中模型的逻辑子对象
【发布时间】:2011-02-21 17:42:43
【问题描述】:

使用 MVVM,一种类型的 ViewModel 包含它们作为字段表示的模型。

所以我确实有一个 CompanyModel 和一个 CompanyViewModel,其中有一个 CompanyModel 实例。

这个 CompanyModel 有一个属于它的 Divisions 集合。所以 CompanyModel 有一个 List(或一些集合类)。

现在 CompanyViewModel 希望将这些部门表示为 ObservableCollection<DivisionViewModel>;您可以在 CompanyViewModel 中添加新的部门。

确保 ObservableCollection 和 Models 集合保持同步的最佳方法是什么?所以当我添加一个新的 DivisionViewModel 并保存时,它会自动将其模型保存到 CompanyModel 的List<Division>

我有更多像这样的父/子关系的类,所以我希望我可以在 AbstractViewModel 类中重用或实现一些东西。

注意:我的 ViewModel 实现了 IEditableObject

【问题讨论】:

  • 我会使用 INotifyCollectionChanged 事件。但实际上它取决于一项任务。如果您想从服务接收模型并保存它,那么同步没有意义。

标签: wpf collections mvvm observablecollection


【解决方案1】:

可能最简单的方法是创建一个继承自 ObservableCollection 的新类,并将源列表以及各种初始化和映射函数作为参数。它的签名可能看起来像这样:

public class SynchronizedObservableCollection<TDest, TSource> : ObservableCollection
{
    public SynchronizedObservableCollection(
        IList<TSource> source, 
        Func<TSource, TDest> newDestFunc, 
        Func<TDest, TSource> newSourceFunc),
        Func<TSource, TDest, bool> mapSourceToDestFunc
    {
        // Initialize the class here.
    }
}

然后您需要处理 CollectionChanged 事件,在添加新的 Destination 实例时创建新的 Source 实例,在删除现有的 Destination 实例时删除现有的 Source 实例,诸如此类。您将使用上面的“新”函数来创建各种实体的新实例,并且您将在各种 Linq 查询中使用上面的“映射”函数,这些函数可以让您弄清楚您的视图模型的哪个实例ObservableCollection 映射到 List 中的模型。

您可能会在上面的示例中使用它,也许:

var divisionViewModels = new SynchronizedObservableCollection(
    company.DivisionList, 
    division => new DivisionViewModel(division),
    divisionVm => divisionVm.Model,
    (division, divisionVm) => divisionVm.Model == division);

具体的实现留给读者作为练习:-)。但是我在以前的项目中使用过这样的类并取得了一些成功。只需确保围绕它进行了一些好的单元测试,这样你就知道你可以依赖它,而不必花费大量时间在事件处理调用堆栈中寻找。

【讨论】:

  • 我喜欢它。我现在主要将其视为一种单向传输,但我想如果我将两个集合都设为 Observable,您可以双向传输。这是 Observable 仅适用于 WPF/Silverlight 的充分理由。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 2016-12-24
  • 1970-01-01
相关资源
最近更新 更多