Для чего нужен DataContext? - PullRequest
32 голосов
/ 31 августа 2011

Как продолжение вопроса Связывание 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 ]

89 голосов
/ 31 августа 2011

Когда вы пишете

<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» вы говорите?

3 голосов
/ 19 октября 2013

От CodeProject от Кишора Гаддама:

DataContext является одним из самых фундаментальных понятий в привязке данных. Объект Binding должен откуда-то получать свои данные, и есть несколько способов указать источник данных, например, использовать свойство Source непосредственно в Binding, наследуя DataContext от ближайшего элемента при обходе в дереве, устанавливая свойства ElementName и RelativeSource в объекте Binding.

Подробный пример для CodeProject: http://www.codeproject.com/Articles/321899/DataContext-in-WPF

1 голос
/ 31 августа 2011

В большинстве случаев вы делаете хотите связать с DataContext, в некоторых шаблонах на ItemsControls это единственный способ привязки к текущему шаблонному элементу, например.Дальнейшие привязки к DataContext приятно писать и читать, поскольку они лаконичны.

В вашем примере вы все равно можете установить DataContext, вам нужно только изменить привязку в Настройках соответственно:

<Controls:SearchSettings DataContext="{Binding Settings}" Settings="{Binding}"/>
1 голос
/ 31 августа 2011

В этом конкретном случае вы можете сделать:

<Controls:SearchSettings DataContext="{Binding Path=Settings}" Settings="{Binding}" />

Предполагая, что вы хотите, чтобы все, что может быть содержимым SearchSettings, использовало Настройки в качестве контекста данных. По сути, DataContext влияет на сам элемент и любые потомки, которые явно не переопределяют его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...