我的模型中有一个由级别和实体组成的2级层次结构,托管在根对象中,我希望在TreeView
中显示它们。
Root object
L Constellations
L Entities
我的RootObjectViewModel
暴露了我的根对象。在那,我完全同意在MVVM best practices中的Bryan Lagunas,模型对象应该由视图模型公开而不是外观。顺便说一句优秀的视频,真的值得花时间。
我到处读到TreeView.ItemsSource
应该映射到一组视图模型,也就是说,对于我的Constellation集合,我的RootObjectViewModel
应该提供ConstellationViewModel
的集合。
我担心的是,如果我的星座集合和其中的实体是实时的,也就是说,如果某些项目被添加,更改(它们的顺序)或被删除,我必须在我的ViewModels集合中手动反映这些变化。
我会发现将ItemsSource
映射到Constellation本身的集合会更优雅,这样模型中的任何更改都会反映出来而不会重复,然后有一些转换器来映射{ {1}}基于星座模型TreeViewItems.DataContext
。
如果这还不够清楚,我可以用一些示例代码来澄清这一点。
是否有人面临同样的问题和/或尝试实施此问题?
提前感谢您的帮助。
塞德里克
答案 0 :(得分:0)
这取决于。如果您的模型具有视图所需的属性,并且视图可以在用户点击时直接更改它们,则可以公开模型。
但是,如果您的模型是,例如,只读并需要调用服务来应用更改,则必须将其包装在视图模型中,以便为视图提供可写属性。
答案 1 :(得分:0)
搞定了!
不可能开箱即用,这就是原因:
可以将模型集合用作项目源,并使用转换器来获取TreeViewItem
内部组件的相应视图模型。但是没有任何方法可以干扰创建TreeViewItem
以将转换器应用于其DataContext
。这意味着TreeViewItem
的属性无法绑定到ViewModel。
换句话说:
TreeView
的标准行为,而不必处理TreeViewItems
属性,如果您的集合未更改或可以实现{{1}如果你的模型没有改变或者可以实现ICollectionChanged
,那么可以使用模型的集合。现在,我实现了一个名为IPropertyChanged
的集合类型,它使用原始集合作为输入,并使用此输入同步其自己的内容。这只是一个基础课程,有许多改进方法,但它有效。您所要做的就是将此集合用作VM属性,设置原始集合和转换器,并将ItemsSource绑定到此集合。
这是完整的代码:
ConvertingCollection<Tin, Tout>
我在Github上创建了一个名为MVVMTreeViewPOC的项目给POC这个想法。它工作正常,它是展示限制的好工具。
塞德里克。