Когда вы пишете
<Label name="myLabel" Content="{Binding Path=Name}" />
, вы привязываетесь к myLabel.DataContext.Name
, а не myLabel.Name
.
XAML в WPF - это просто симпатичный пользовательский интерфейс для отображения и взаимодействия сфактические данные, иначе известные как 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 основан накакие бы данные не находились за объектом пользовательского интерфейса.
Обновление: Я так часто вижу этот вопрос от новых пользователей WPF, что я расширил этот ответ до поста в моем блоге: Что это«DataContext» вы говорите?