MVVM:处理集合中模型的逻辑子对象

发布于 2024-10-18 10:41:07 字数 584 浏览 1 评论 0原文

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

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

该 CompanyModel 有一组属于它的部门。所以 CompanyModel 有一个 List (或一些集合类)。

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

确保 ObservableCollection 和 Models 集合保持同步的最佳方法是什么?因此,当我添加新的 DivisionViewModel 并保存它时,它会自动将其模型保存到 CompanyModel 的 List 中吗?

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

注意:我的 ViewModel 实现 IEditableObject

Using MVVM, one type of ViewModels include the Model they represnt as a Field.

So I do have a CompanyModel and a CompanyViewModel that has one instance of CompanyModel.

This CompanyModel has a collection of Divisions belonging to it. So CompanyModel has a List (or some collection class).

Now the CompanyViewModel would want to represent these Divisions as an ObservableCollection<DivisionViewModel>; and you you could add new Divisions in the CompanyViewModel.

What is the best way ensure that the ObservableCollection and the Models collection stay in sync? So when I add a new DivisionViewModel and save it, it automatically saves its model to the CompanyModel's List<Division>?

I have more classes like this Parent/child relations so I would love something I could reuse or implement perhaps in a AbstractViewModel class.

Note: My ViewModels implement IEditableObject

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离旧人 2024-10-25 10:41:07

最简单的方法可能是创建一个继承自 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 映射到列表中的模型。

您可能会在上面的示例中使用它,如下所示:

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

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

Probably the easiest way to do this is to create a new class that inherits from ObservableCollection, and which takes a source list and various initialization and mapping functions as parameters. Its signature might look something like this:

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

You'd then want handle the CollectionChanged event, creating new Source instances when a new Destination instance got added, deleting existing Source instances when an existing Destination instance got deleted, that sort of thing. You'd use the "new" functions above to create new instances of the various entities, and you'd use the "map" functions above in various Linq queries that would allow you to figure out, say, which instance of a viewmodel your ObservableCollection mapped to a model in your List.

You would use it in your example above like so, perhaps:

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

The exact implementation is left as an exercise to the reader :-). But I've used classes like this with some success in previous projects. Just make sure you work up some good unit tests around it, so that you know you can rely on it, and don't have to spend a lot of time hunting through event-handling callstacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文