当你写代码时
<Label name="myLabel" Content="{Binding Path=Name}" />
你正在绑定到myLabel.DataContext.Name
,而不是myLabel.Name
。
在WPF中,XAML只是一个漂亮的用户界面,用于显示和与实际数据交互,也就是DataContext
。其他绑定源(例如RelativeSource
、ElementName
等)的目的是指向另一个属性,该属性不存在于当前控件的DataContext
中。
假设有一个窗口。如果没有设置DataContext
,则窗口仍会显示,但其后面没有数据。
现在假设设置了myWindow.DataContext = new ClassA();
。现在窗口显示的数据是ClassA
。如果ClassA
有一个名为Name
的属性,我可以编写一个标签并将其绑定到Name
(例如您的示例),无论存储在ClassA.Name
中的值是什么,都会被显示。
现在,假设ClassA
有一个ClassB
属性,并且两个类都有一个叫做Name
的属性。以下是一段XAML代码块,说明了DataContext
的目的,并展示了如何引用自己的DataContext
中不存在的属性。
<Window x:Name="myWindow"> <!-- DataContext is set to ClassA -->
<StackPanel> <!-- DataContext is set to ClassA -->
<!-- DataContext is set to ClassA, so will display ClassA.Name -->
<Label Content="{Binding Name}" />
<!-- DataContext is still ClassA, however we are setting it to ClassA.ClassB -->
<StackPanel DataContext="{Binding ClassB}">
<!-- DataContext is set to ClassB, so will display ClassB.Name -->
<Label Content="{Binding Name}" />
<!-- DataContext is still ClassB, but we are binding to the Window's DataContext.Name which is ClassA.Name -->
<Label Content="{Binding ElementName=myWindow, Path=DataContext.Name}" />
</StackPanel>
</StackPanel>
</Window>
正如您所看到的,DataContext基于UI对象后面的任何数据。
更新:我经常从新的WPF用户那里看到这个问题,因此我将这个答案扩展为我的博客文章:“DataContext”是什么?
Content={Binding Name}
时,它绑定到了Label.DataContext.Name
而不是我希望它执行的Label.Parent.DataContext.Name
。 - Eugene Strizhok