Подтвердить что ты не робот

Для чего нужен 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?

4b9b3361

Ответ 1

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

<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 DataContext.Name which is ClassA.Name -->
            <Label Content="{Binding ElementName=myWindow, Path=DataContext.Name}" /> 
        </StackPanel>
    </StackPanel>
</Window>

Как вы можете видеть, DataContext основан на любых данных, находящихся за объектом пользовательского интерфейса.

Обновление: Я так часто вижу этот вопрос у новых пользователей WPF, что я расширил этот ответ в сообщении в своем блоге: Что это "DataContext" , о котором вы говорите?

Ответ 2

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

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

Предполагая, что вы хотите, чтобы все содержимое ContentSettings содержало настройки в качестве контекста данных. В принципе, DataContext влияет на сам элемент как на потомков, которые явно не переопределяют его.

Ответ 3

От CodeProject от kishore Gaddam:

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

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

Ответ 4

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

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

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