DataContext 用于将 UserControl 与 DataTemplate 中的 ViewModel 绑定
我想要实现的是:
- 将 ListView 绑定到 ItemRecords 的 ObservableCollection。
- 拥有一个 TabControl,其中包含 ListView 中选择进行编辑的所有 ItemRecord 的详细视图。
- 每个 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>
任何好的建议将不胜感激!
Alex
What I'm trying to achieve is:
- Have a ListView bound to an ObservableCollection of ItemRecords.
- Have a TabControl that contains detailed view for all the ItemRecords in the ListView that were selected for editing.
- Each TabItem contains a UserControl ("ItemInfo") that uses ItemInfoViewModel as its VM (and, not so coincidentally, DataContext).
- ItemInfo UserControl needs to be populated with the data from the corresponding ItemRecord.
To achieve that, I'm trying to pass the ItemRecord (selected in the ListView) to ItemInfoViewModel.
Finally, the question: what do you think would be the best way to do this, without breaking the MVVM pattern?
The not-so-elegant way that I see (and it actually doesn't exactly follow the MVVM principles) is to have a DependencyProperty ItemRecord defined in the UserControl, provide its value via binding, and in the constructor (in the UserControl's code-behind) pass the ItemRecord to the VM (which we get by casting the DataContext).
The other problem is with how to actually pass the ItemRecord via binding.
Once I set the VM as the UserControl's DataContext, I cannot just use {Binding}
to specify the current item in TabControl's source collection.
At the moment I am binding to the TabControl's SelectedItem using ElementName - but this doesn't sound too robust :-(
<localControls:TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer>
<localControls:ItemInfo ItemRecord="{Binding ElementName=Tabs, Path=SelectedItem}"/>
</ScrollViewer>
</DataTemplate>
</localControls:TabControl.ContentTemplate>
Any good advice will be greatly appreciated!
Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你的问题是你不太理解 MVVM 模式;您仍然将其视为不同的控件相互通信。在 MVVM 中,它们不应该这样,每个控件都独立于所有其他控件与视图模型进行通信。视图模型控制(并提供)告诉控件如何行为的逻辑。
因此,理想情况下,您应该有类似的内容:
ListViewRecords
将绑定到ListView
的ItemsSource
属性(实际属性可能会有所不同,具体取决于你正在使用的具体控件,我现在已经习惯了 Telerik 套件,所以这就是我的想法)。SelectedListViewRecords
将绑定到ListView
的SelectedItems
属性。然后,对于 TabControl,您将拥有:同样,您将
Items
属性绑定到Tabs
,将SelectedItem
绑定到SelectedTabTabControl
上的 code>。现在您的视图模型包含所有逻辑,因此在您的SelectedListViewRecords
中您可能会执行以下操作:因此这里的想法是控件除了发送和接收属性更改之外什么也不做,它们对底层数据、逻辑等。它们只是显示其绑定属性告诉它们要显示的内容。
I think your problem is you're not quite understanding the MVVM pattern here; you're still looking at this as the different controls talking to each other. Where in MVVM, they should not be, each control is communicating with the view model independently of all the others. And the view model controls (and supplies) the logic which tells the controls how to behave.
So, ideally you would have something like:
The
ListViewRecords
would be bound to theItemsSource
property of yourListView
(the actual properties might vary based on the specific controls you're using, I'm used to the Telerik suite at the moment so that's where my head is). And theSelectedListViewRecords
would be bound to theSelectedItems
property of theListView
. Then for your TabControl you would have:Again, you would bind the
Items
property to theTabs
andSelectedItem
to theSelectedTab
on yourTabControl
. Now your view model contains all the logic, so in yourSelectedListViewRecords
you might do something like this:So the idea here is that the controls do nothing more than send and receive property changes, they know nothing of the underlying data, logic, etc. They simply show what their bound properties tell them to show.