【发布时间】:2011-09-20 20:02:25
【问题描述】:
我想要实现的是:
- 将 ListView 绑定到 ItemRecords 的 ObservableCollection。
- 拥有一个 TabControl,其中包含 ListView 中选择进行编辑的所有 ItemRecords 的详细视图。
- 每个 TabItem 都包含一个 UserControl(“ItemInfo”),它使用 ItemInfoViewModel 作为其 VM(以及,并非巧合的是,DataContext)。
- ItemInfo UserControl 需要使用相应 ItemRecord 中的数据进行填充。
为此,我尝试将 ItemRecord(在 ListView 中选择)传递给 ItemInfoViewModel。
最后,问题:在不破坏 MVVM 模式的情况下,您认为最好的方法是什么?
我看到的不太优雅的方式(它实际上并不完全遵循 MVVM 原则)是在 UserControl 中定义一个 DependencyProperty ItemRecord,通过绑定提供它的值,并在构造函数中(在UserControl 的代码隐藏)将 ItemRecord 传递给 VM(我们通过转换 DataContext 获得)。
另一个问题是如何通过绑定实际传递 ItemRecord。
一旦我将 VM 设置为 UserControl 的 DataContext,我就不能只使用{Binding} 来指定 TabControl 的源集合中的当前项。
目前我正在使用 ElementName 绑定到 TabControl 的 SelectedItem - 但这听起来不太健壮:-(
<localControls:TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer>
<localControls:ItemInfo ItemRecord="{Binding ElementName=Tabs, Path=SelectedItem}"/>
</ScrollViewer>
</DataTemplate>
</localControls:TabControl.ContentTemplate>
任何好的建议将不胜感激!
亚历克斯
【问题讨论】:
-
“它实际上并不完全遵循 MVVM 原则”确实如此。难道TextBox的Text属性不遵循MVVM原则吗? UserControl 关心视图的职责。它不应该执行业务逻辑,但它当然可以公开可以绑定到 DataContext 的属性。
-
@Will:在这一点上我恐怕还没有说清楚。我的意思是,将属性值从 View 的代码隐藏推送到 ViewModel 并不是那么优雅。
-
不,你说得很清楚。 MVVM != 后面没有代码。这就是我的观点。 MVVM 是关于关注点分离的。视图与视图有关。如果您没有创建实际的控件,那么您就是在 UserControl 中合成控件。一样的区别。如果您没有在自定义控件中公开公共 DP,那么您就是在 UserControl 的代码隐藏中执行此操作。代码隐藏不是反 MVVM,当您将业务关注点与视图关注点混合在一起时,您就打破了这种模式。
标签: wpf data-binding mvvm