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,这也将无法工作。