Tor*_*ten 11 collections wpf mvvm viewmodel
我对C#/ WPF的MVVM设计有疑问.我看过几个演示应用程序,但它们并没有真正解决我的问题.我的应用程序由包含其他对象的对象组成.就像父子关系一样.
我现在的问题是:
我有以下情况:
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);
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,ParentVM包含ChildVM,但实际的Parent(在ParentVM内)没有ChildVM对象包含的Child对象.我也认为复制Child对象不是一个好主意,因为它会导致冗余,在我的应用程序上下文中也没有必要/可能创建新的Child对象.
我还考虑过以下课程设计:
class ParentVM {
Parent _parent;
string Name{return _parent.Name;}
List<Child> children {get{return _parent.Children;}}
}
Run Code Online (Sandbox Code Playgroud)
但是,这意味着如果我想操作ParentVM的Child对象,我会直接对Model进行操作.
另一方面,我可以简单地将(Model)Parent留空,并使用ParentVM在数据库中创建一个新的Parent.但这是处理问题的好方法吗?
Mar*_*eIV 16
实际上,执行此操作的正确方法是在首次创建ParentVM时,遍历传入的Parent的子节点,为每个子节点创建一个ChildVM,然后将这些ChildVM对象添加到ParentVM的ChildVMs属性中.(有些人会把这个属性称为'儿童',但我个人喜欢明确它是ChildVMs的集合,而不是Child对象的集合.只需添加'VM'后缀就可以了.
然后,您还必须收听实际Parent's Children集合的更改通知,并相应地更新您的ChildVMs集合.
那样你就有了一个带有Parent-> Children-> Child的模型和一个ParentVM的ViewModel-> ChildVMs-> ChildVM,我相信你想要的.
现在我也相信你应该能够直接从ParentVM公开Parent以及直接从ChildVM公开Child,因为你的UI可能绑定到这些项目的各种属性,例如上面的Name属性.然而,MV-VM纯粹主义者会说永远不会这样说UI永远不会知道模型,因为如果模型发生变化,你必须改变UI.我的论点是,如果模型发生变化,你必须以完全相同的理由改变ViewModel.唯一的节省是如果有几个视图都共享相同的ViewModel,因为你只需要在一个地方更改它,但实际上,像'Name'这样的东西不会改变它从模型到它的"名称" ViewModel所以在这些情况下它无论如何都是非参数.
另外,通过以"纯粹"方式进行操作会产生性能开销,因为您不能像上面使用Name那样简单地委托模型项,因为视图将不会知道任何模型生成的更改除非您还在VM中添加了所有额外更改通知,这意味着您现在在模型中有一个更改通知,其唯一目的是在VM中触发第二个更改通知,然后通知UI.纯?是.业绩创?您打赌,特别是在进行大量更改并且您正在使用INotifyPropertyChanged接口时,因为这意味着您必须在更改处理程序中进行字符串比较以检测并委派所有这些更改!但是,如果直接绑定到ParentVM.Parent.Name属性,则您已经从模型中获得了更改通知以通知UI,并且还可以使VM保持干净,以用于仅特定于VM或视图的事物.
然而,我从未做过的是在模型中放置任何仅查看信息的内容.对我来说就是ViewModel的用途.因此,例如,如果孩子们有一个基于枚举或其他的特定颜色,那对我来说就是ChildVM而不是模型本身,如果模型中有任何属性决定颜色,就像枚举的属性,在这种情况下,是的,我会在ChildVM内部连接模型的更改通知.(说实话,我甚至可以通过UI中的颜色转换器直接进行,仍然绑定到模型的枚举.这实际上是一个案例.)
HTH,
标记