Для чего нужен DataContext?
В продолжение вопроса Связывание DataContext с другим свойством в WPF.
В самом конце исследования я был очень удивлен, обнаружив, что когда кто-то пишет что-то вроде этого:
<Label Content="{Binding Path=Name}" />
DataContext
против которого Content
свойство связано Label
контролировать себя! Тот факт, что он все еще работает, обусловлен наследованием по умолчанию значения DataContext от ближайшего родителя.
Но если у вас есть эта метка, завернутая в пользовательский элемент управления, и вы не хотите связывать свои данные с DataContext
свойство этого контроля, вы бы скорее хотели иметь:
<Controls:SearchSettings Settings="{Binding Path=Settings}" />
И вот ты здесь. Теперь вам нужно установить Settings
как DataContext
для SearchSettings
контроль, для Label
внутри, чтобы связать, но вы не можете, потому что это вызовет повторное связывание Settings
имущество.
Я не вижу смысла в смешивании свойств привязки с использованием разных источников: DataContext
, от ElementName
и т. д. Так зачем мне использовать DataContext
?
4 ответа
Когда ты пишешь
<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", о котором вы говорите?
Из CodeProject Кишора Гаддама:
DataContext
является одним из самых фундаментальных понятий в привязке данных. Объект Binding должен откуда-то получать свои данные, и есть несколько способов указать источник данных, например, используя свойство Source непосредственно в Binding, наследуяDataContext
от ближайшего элемента при перемещении вверх по дереву, установивElementName
а такжеRelativeSource
свойства в объекте Binding.
Подробный пример по CodeProject: http://www.codeproject.com/Articles/321899/DataContext-in-WPF
В этом конкретном случае вы можете сделать:
<Controls:SearchSettings DataContext="{Binding Path=Settings}" Settings="{Binding}" />
Предполагая, что вы хотите, чтобы все, что может быть содержимым SearchSettings, использовало Настройки в качестве контекста данных. По сути, DataContext влияет на сам элемент и любые потомки, которые явно не переопределяют его.
В большинстве случаев вы действительно хотите привязать к DataContext, в некоторых шаблонах на ItemsControls это единственный способ привязки к текущему шаблонному элементу, например. Дальнейшие привязки к DataContext приятно писать и читать, поскольку они являются краткими.
В вашем примере вы все еще можете установить DataContext, вам нужно только изменить привязку в настройках соответственно:
<Controls:SearchSettings DataContext="{Binding Settings}" Settings="{Binding}"/>