WPF MVVM:设置选项卡视图的DataContext [英] WPF MVVM: Setting DataContext of Tab Views
问题描述
我在此处中描述了一种奇怪的绑定行为.我进行了大量的故障排除,得出的结论是,最可能的问题在于如何设置每个选项卡视图的DataContext
.
I have experienced a weird binding behavior that is described here. I did a lot of troubleshooting and I came to the conclusion that the most likely problem lies at how I set the DataContext
of each of the tab's view.
我有一个TabControl
,其ItemsSource
绑定到ViewModels
的列表.
I have a TabControl
whose ItemsSource
is bound to a list of ViewModels
.
MainView:
<TabControl ItemsSource="{Binding TabList}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type vm:Tab1ViewModel}">
<v:Tab1 />
</DataTemplate>
</TabControl.Resources>
...
</TabControl>
MainViewModel:
public ObservableCollection<TabViewModelBase> TabList { get; set; }
public MainViewModel()
{
this.TabList = new ObservableCollection<TabViewModelBase>();
// Tab1ViewModel is derived from TabViewModelBase
this.TabList.Add(new Tab1ViewModel());
}
因此,现在MainViewModel
有一个TabViewModelBase
列表,我相信这是执行此操作的正确MVVM方法. TabViewModelBase
的视图(Tab1
)是使用DataTemplate
定义的.
So, now the MainViewModel
has a list of TabViewModelBase
, which I believe is the correct MVVM way to do this. The view (Tab1
) for TabViewModelBase
is defined using DataTemplate
.
这是问题所在:
Tab1:
<UserControl.Resources>
<vm:Tab1ViewModel x:Key="VM" />
</UserControl.Resources>
<UserControl.DataContext>
<StaticResourceExtension ResourceKey="VM" />
</UserControl.DataContext>
我认为大多数人也会这样做,但是... 这种方法有些严重错误!
I think most people would do this as well, but... There is something terribly wrong with this approach!
在MainViewModel
中,我手动实例化了Tab1ViewModel
.在MainView
中,我使用DataTemplate
告诉视图在看到Tab1ViewModel
时使用Tab1
.这意味着MainView
将实例化Tab1
类的对象.
In MainViewModel
, I have manually instantiated a Tab1ViewModel
. In MainView
, I used DataTemplate
to tell the View to use a Tab1
whenever it sees a Tab1ViewModel
. That means MainView
would instantiate an object of Tab1
class.
现在,Tab1
需要其DataContext
与自己的Tab1ViewModel
进行绑定,因此我们使用StaticResource
添加一个Tab1ViewModel
,只是这是一个全新的实例!
Now, Tab1
needs its DataContext
to do binding with its own Tab1ViewModel
, so we use StaticResource
to add one Tab1ViewModel
, except that this is a brand new instance!
我需要将DataContext
设置回在MainViewModel
中实例化的原始位置.那么,如何在DataTemplate
中设置Tab1
的DataContext
?
I need to set the DataContext
back to the original one that I instantiated in MainViewModel
. So, how do I set the DataContext
of Tab1
within DataTemplate
?
推荐答案
您不必在XAML中指定vm:Tab1ViewModel
新实例.您也不需要显式定义DataContext
.只要ViewModel
的类型与您在DataTemplate
中定义的类型相匹配的粒子view
都将呈现且与ViewModel
相同的DataContext
,则列表中的每个项目都是ViewModel
.例如,如果list具有以下两个对象:
You don't have to specify vm:Tab1ViewModel
new instance in your XAML. Neither do you need to define the DataContext
explicitly. Every item of your list is a ViewModel
whenever the type of a ViewModel
matched with the type you have defined in DataTemplate
a particulate view
will be rendered and with the same DataContext
as ViewModel
. For example if list has two objects like below:
public ObservableCollection<TabViewModelBase> TabList { get; set; }
public MainViewModel()
{
this.TabList = new ObservableCollection<TabViewModelBase>();
this.TabList.Add(new Tab1ViewModel1());
this.TabList.Add(new Tab1ViewModel2());
}
而您的DataTemplate
是:
<TabControl ItemsSource="{Binding TabList}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type vm:Tab1ViewModel}">
<v:Tab1 />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:Tab1ViewModel2}">
<v:Tab2 />
</DataTemplate>
</TabControl.Resources>
...
然后两个选项卡将呈现
Tab1
&Tab2
(原因列表包含2个项目).Tab1
将具有Tab1ViewModel1
作为DataContext
,而Tab2
将具有Tab1ViewModel2
作为DataContext
.您无需指定DataContext
then Two tabs will be renders
Tab1
&Tab2
(cause list has 2 items).Tab1
will haveTab1ViewModel1
asDataContext
and andTab2
will haveTab1ViewModel2
asDataContext
. You need not specifyDataContext
explicitly.
这篇关于WPF MVVM:设置选项卡视图的DataContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!