Для чего нужен 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}"/>
Другие вопросы по тегам