代码之家  ›  专栏  ›  技术社区  ›  Torsten

如何在ViewModel中显示(视图)模型的集合

  •  11
  • Torsten  · 技术社区  · 15 年前

    我现在的问题是:

    • “子对象”属性必须是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,但实际的父对象(位于ParentVM内部)没有ChildVM对象包含的子对象。我也不认为复制子对象是个好主意,因为它会导致冗余,在我的应用程序上下文中,也不需要/可能创建新的子对象。

    我还考虑了以下课堂设计:

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

    然而,这意味着如果我想操作ParentVM的子对象,我将直接对模型进行操作。

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

    2 回复  |  直到 11 年前
        1
  •  16
  •   Mark A. Donohoe    13 年前

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

    这样,您就有了一个具有父级的模型->儿童->ParentVM的子对象和视图模型->ChildVMs->这就是我相信你想要的。

    现在我还相信,您应该能够直接从ParentVM公开父级,也可以直接从ChildVM公开子级,因为您的UI可能绑定到这些项上的各种属性,例如上面的Name属性。然而,M-V-VM纯粹主义者会说永远不要这样做,说UI永远不应该知道模型,因为如果模型改变了,就必须改变UI。我的论点是,如果模型发生变化,出于完全相同的原因,您必须改变ViewModel。唯一的节约是,如果有多个视图共享同一个ViewModel,因为您只需在一个位置更改它,但实际上,“名称”之类的内容不会将其“名称”从模型更改为ViewModel,因此在这些情况下,它无论如何都不是参数。

    VM中的更改通知,然后通知UI。纯净的对性能测试?当然,尤其是当大量更改正在进行且您正在使用INotifyPropertyChanged接口时,因为这意味着您必须在更改处理程序中进行字符串比较,以检测和委派所有这些更改!但是,如果您直接绑定到ParentVM.Parent.Name属性,那么您将已经收到来自模型的更改通知,以通知UI,并且您还可以保持VM干净,只针对特定于VM或视图的内容。

    但是,我从来没有在模型中放置任何只显示视图信息的内容。这就是ViewModel的用途。例如,如果孩子们有一个基于枚举或其他什么的特定颜色,对我来说,这是ChildVM中的东西,而不是模型本身,如果模型中有任何属性指定该颜色,比如枚举的属性,在这种情况下,是的,我会从ChildVM内的模型连接更改通知。(老实说,我甚至可以直接通过UI中的颜色转换器来实现,仍然绑定到模型的枚举。这实际上是一件逐案处理的事情。)

    做记号

        2
  •  1
  •   Torsten    15 年前

    好的,我从一个.NET论坛得到了一些帮助和建议: