XAML 中的 WPF DataContext,为什么以及正确的方法是什么
WPF DataContext in XAML, why and what's the correct approach
目前这是我在 MVVM 中为我的 Windows 和 UserConrols
设置 DataContext 的方式
<UserControl.DataContext>
<local:DataMainViewModel x:Name="vm"/>
</UserControl.DataContext>
然而,有人告诉我永远不要这样做,但我看到了很多例子,很多代码都在这样做。我之前 运行 遇到了一些奇怪的问题,例如 DataContext 在我看来没有相同的实例,不确定。
无论如何,我只是想问一下,最好的方法是什么?我可以在 XAML 中保留这种方法吗?
我听说我应该删除它,而不是在视图中设置,例如...
public DataMainView()
{
InitializeComponent();
DataContext = new DataMainViewModel();
}
最好和最安全的方法是什么?
我一直在 XAML 中设置它的原因是因为我喜欢 XAML 的设计方法,使代码更清晰,最重要的是,我获得了绑定的智能感知。如果我应该在 XAML 中删除它,请分享我如何在不在 XAML 中设置 DataContext 的情况下获得绑定的智能感知。因为如果我把它放在代码后面,我就不会再获得智能感知了,当我尝试绑定对象时,我必须从引用我的视图模型中正确键入所有内容。
谢谢,
蒂姆
您根本不应该显式设置 UserControls 的 DataContext,无论是在 XAML 还是在代码隐藏中。
UserControl 应该从其父元素继承其 DataContext 属性 的值,并将其属性绑定到继承的 DataContext 中对象的属性。
这通常看起来像
<Window ...>
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
...
<local:MyUserControl MyProperty="{Binding VmProperty}" .../>
</Window>
其中 VmProperty 是 MainViewModel 的 属性。如果主视图模型提供了一个子视图模型,该子视图模型具有要由 UserControl 显示的属性,则绑定可能看起来像
<local:MyUserControl MyProperty="{Binding SubViewModel.SubVmProperty}" .../>
当 UserControl 明确设置了自己的 DataContext 时,这些绑定将不起作用。
或者,UserControl XAML 中的元素也可以直接绑定到 DataContext 对象的属性,例如
<UserControl x:Class="MyNamespace.MyUserControl" ...>
...
<TextBlock Text="{Binding SubVmProperty}"/>
...
</UserControl>
您将在哪里实例化控件,例如
<local:MyUserControl DataContext="{Binding SubViewModel}"/>
如果 UserControl 设置了自己的 DataContext,上述绑定也会失败。
UserControl 通常由 DataTemplate 实例化,例如
<DataTemplate DataType="{x:Type local:SubViewModel}">
<local:MyUserControl/>
</DataTemplate>
其中 DataContext 自动分配给应用了 DataTemplate 的对象。如果 UserControl 明确设置了自己的 DataContext,这也将无法工作。
目前这是我在 MVVM 中为我的 Windows 和 UserConrols
设置 DataContext 的方式<UserControl.DataContext>
<local:DataMainViewModel x:Name="vm"/>
</UserControl.DataContext>
然而,有人告诉我永远不要这样做,但我看到了很多例子,很多代码都在这样做。我之前 运行 遇到了一些奇怪的问题,例如 DataContext 在我看来没有相同的实例,不确定。
无论如何,我只是想问一下,最好的方法是什么?我可以在 XAML 中保留这种方法吗? 我听说我应该删除它,而不是在视图中设置,例如...
public DataMainView()
{
InitializeComponent();
DataContext = new DataMainViewModel();
}
最好和最安全的方法是什么?
我一直在 XAML 中设置它的原因是因为我喜欢 XAML 的设计方法,使代码更清晰,最重要的是,我获得了绑定的智能感知。如果我应该在 XAML 中删除它,请分享我如何在不在 XAML 中设置 DataContext 的情况下获得绑定的智能感知。因为如果我把它放在代码后面,我就不会再获得智能感知了,当我尝试绑定对象时,我必须从引用我的视图模型中正确键入所有内容。
谢谢, 蒂姆
您根本不应该显式设置 UserControls 的 DataContext,无论是在 XAML 还是在代码隐藏中。
UserControl 应该从其父元素继承其 DataContext 属性 的值,并将其属性绑定到继承的 DataContext 中对象的属性。
这通常看起来像
<Window ...>
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
...
<local:MyUserControl MyProperty="{Binding VmProperty}" .../>
</Window>
其中 VmProperty 是 MainViewModel 的 属性。如果主视图模型提供了一个子视图模型,该子视图模型具有要由 UserControl 显示的属性,则绑定可能看起来像
<local:MyUserControl MyProperty="{Binding SubViewModel.SubVmProperty}" .../>
当 UserControl 明确设置了自己的 DataContext 时,这些绑定将不起作用。
或者,UserControl XAML 中的元素也可以直接绑定到 DataContext 对象的属性,例如
<UserControl x:Class="MyNamespace.MyUserControl" ...>
...
<TextBlock Text="{Binding SubVmProperty}"/>
...
</UserControl>
您将在哪里实例化控件,例如
<local:MyUserControl DataContext="{Binding SubViewModel}"/>
如果 UserControl 设置了自己的 DataContext,上述绑定也会失败。
UserControl 通常由 DataTemplate 实例化,例如
<DataTemplate DataType="{x:Type local:SubViewModel}">
<local:MyUserControl/>
</DataTemplate>
其中 DataContext 自动分配给应用了 DataTemplate 的对象。如果 UserControl 明确设置了自己的 DataContext,这也将无法工作。