gpt4 book ai didi

wpf - 如何在 ViewModel 中呈现( View )模型的集合

转载 作者:行者123 更新时间:2023-12-04 01:53:26 24 4
gpt4 key购买 nike

我对 C#/WPF 的 MVVM 设计有疑问。我看过几个演示应用程序,但它们并没有真正解决我的问题。
我的应用程序由包含其他对象的对象组成。很像亲子关系。

我现在的问题是:

  • children 属性是否必须是 ViewModel
  • 如果是这样,我如何创建新的父对象,其中包含 现有通过 ViewModel 的子对象?

  • 我有以下情况:
    class Child {
    string Name;
    }

    class ChildVM {
    Child _child;
    string Name{return _child.Name;}
    }

    class Parent {
    string Name;
    List<Child> children;
    }

    class ParentVM{
    Parent _parent;

    string Name{return _parent.Name;}
    List<ChildVM> children {get;set;}

    ParentVM(Parent p){_parent = p;}
    }

    void CreateANewParent(){
    List<ChildVM> children = new List<ChildVM>(){new ChildVM(new Child()),...};
    ParentVM parent = new ParentVM(new Parent());
    foreach(ChildVM child in children)
    parent.children.Add(child);
    }

    这里的问题是,ParentVM 包含 ChildVM,但实际的 Parent(位于 ParentVM 内部)没有 ChildVM 对象包含的 Child 对象。我也不认为复制子对象是一个好主意,因为它会导致冗余,并且在我的应用程序上下文中,也不需要/不可能创建新的子对象。

    我还考虑了以下类设计:
    class ParentVM {
    Parent _parent;

    string Name{return _parent.Name;}
    List<Child> children {get{return _parent.Children;}}
    }

    但是,这意味着如果我想操作 ParentVM 的 Child 对象,我将直接对 Model 进行操作。

    另一方面,我可以简单地将 (Model) Parent 留空并使用 ParentVM 在数据库中创建一个新的 Parent。但这是处理问题的好方法吗?

    最佳答案

    实际上,执行此操作的正确方法是当您第一次创建 ParentVM 时,遍历传入的 Parent 的子项,为每个子项创建一个 ChildVM,然后将这些 ChildVM 对象添加到 ParentVM 的 ChildVMs 属性中。 (有些人只会称该属性为“Children”,但我个人喜欢明确它是 ChildVM 的集合,而不是 Child 对象的集合。只需添加“VM”后缀即可非常清楚。

    然后,您还必须收听实际 Parent's Children 集合的更改通知,并相应地更新您的 ChildVMs 集合。

    这样,您就有了一个具有 Parent->Children->Child 的模型和一个 ParentVM->ChildVMs->ChildVM 的 ViewModel,我相信这正是您想要的。

    现在我也相信您应该能够直接从 ParentVM 公开 Parent 以及直接从 ChildVM 公开 Child,因为您的 UI 可能绑定(bind)到这些项目的各种属性,例如上面的 Name 属性。但是 M-V-VM 纯粹主义者会说永远不要这样做,说 UI 永远不应该知道模型,因为如果模型发生变化,您必须更改 UI。我的论点是,如果模型发生变化,出于完全相同的原因,您无论如何都必须更改 ViewModel。唯一的节省是如果有多个 View 都共享相同的 ViewModel,因为您只需要在一个地方更改它,但实际上,像“名称”这样的东西不会将它的“名称”从模型更改为ViewModel 所以在这些情况下它无论如何都是一个非论点。

    另外,通过“纯粹”方式执行它会产生性能开销,因为您不能像上面对 Name 所做的那样简单地委托(delegate)给模型项,因为 View 永远不会知道模型生成的任何更改Name 属性,除非您还在 VM 中添加了所有额外的更改通知,这意味着您现在在模型中有一个更改通知,其唯一目的是在 VM 中触发第二个更改通知,然后通知 UI。纯的?是的。性能侵入?您敢打赌,尤其是在进行大量更改并且您正在使用 INotifyPropertyChanged 接口(interface)时,因为这意味着您必须在更改处理程序中进行字符串比较以检测和委托(delegate)所有这些更改!但是,如果您直接绑定(bind)到 ParentVM.Parent.Name 属性,则您已经从模型中获得了该更改通知来通知 UI,并且您还可以为仅特定于 VM 或 View 的内容保持 VM 清洁。

    然而,我从来没有做的是在模型中放置任何仅供查看的信息。这对我来说就是 ViewModel 的用途。例如,如果 children 有一个基于枚举或其他什么的特定颜色,那对我来说是 ChildVM 中的东西,而不是模型本身,如果模型中有任何属性决定该颜色,比如该枚举的属性,在这种情况下,是的,我会从 ChildVM 内部的模型中连接更改通知。 (说实话,我什至可以直接通过 UI 中的颜色转换器来完成,仍然绑定(bind)到模型的枚举。这真的是一个个案。)

    HTH,

    标记

    关于wpf - 如何在 ViewModel 中呈现( View )模型的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/838950/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com