考虑ViewModel
公开Model
中定义的树,然后将数据绑定到TreeView
。树相当大,模型直接使用,因为它对视图基本上是只读的。现在,TreeView
位于VisualTree中的TabControl
下,因此此时出现的问题是在切换选项卡时不会保留IsExpanded
和IsSelected
属性。有人不愿意将这些布尔属性添加到Model
中的每个节点,因为这应该在ViewModel
中作为原则扩展。树由多态节点组成,因此如果我们要创建一个从树节点类型派生的ViewModel
节点类型并添加这些属性,那么这似乎会导致ViewModel
中的一些毛茸茸的代码:
即,如果树具有抽象NodeBase
,然后是派生类型Node1
,Node1
,... NodeN
(Model
' s Node
s)。然后ViewModel
必须封装这些节点,因此在创建ViewModelNode
时,如果它有Node
的引用,并且每个后代都引用了子ViewModelNode
{ {1}}将每个后代ViewModelNode
的Node一直封装在树下,将Model
中的这些子引用与ViewModel
中维护它们的方式保持一致,同时对Model
的引用。即,Model
节点中的所有引用都在Model
节点中复制,以便ViewModel
节点封装每个Model
节点。这样的冗余引用的存在,即使在ViewModel
的构造函数中处理,也只是闻起来很糟糕。
在这种情况下,最常用的方法是在树中扩展每个节点,而不是如上所述批量复制引用? (在较小的一点上,仅仅提到直接使用模型是不可原谅的犯罪,或者由于情况而被原谅了吗?)
答案 0 :(得分:0)
可能有一个论点要求在模型上实现这些布尔属性是正常的,但我个人希望为TreeView
中的每个模型创建ViewModel。如果您决定实现与TreeView
相关的更多功能,那么这样做的一个优点可能是可扩展性的提高。
我认为这取决于你在TreeView
(在你的应用程序中)实际做了多少,但我认为你做的越多,基于ViewModel的解决方案的论据就越强
关于毛茸茸的代码,您可以使用interface
来描述您的TreeView
成员,从而在一定程度上避开这种情况,例如:
public interface IMyTreeViewItem
{
bool TreeViewItemIsSelected { get; set; }
bool TreeViewItemIsExpanded { get; set; }
// Further potential properties
string TreeViewItemHeaderText { get; set; }
List<IMyTreeViewItem> TreeViewItemChildren { get; set; }
}
此方法可用于确保您的TreeView
成员正确&#34;订阅&#34;。然后还可以选择在XAML中引用interface
类型,例如,TargetType
为HierarchicalDataTemplate
的{{1}}。