Если у вас есть только один элемент управления, который вы хотите привязать к свойству кода, вы можете указать его как источник в привязке через RelativeSource
, например:
<CheckBox ...
IsChecked="{Binding ShowPending, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
Это может быть конец ответа. Но в целом у вас будет несколько элементов управления и вы захотите привязать их к различным свойствам вашего класса. В этом случае удобнее и удобнее использовать тот факт, что свойство DataContext
(которое является исходным объектом по умолчанию для привязки данных) наследуется через иерархию элементов управления, поэтому установка его на верхнем уровне сделает его доступны для всех дочерних элементов управления.
Не существует значения по умолчанию для DataContext
, но есть как минимум два способа установить свойство DataContext
элемента Window так, чтобы оно указывало на себя:
- Путем установки
DataContext = this
в конструкторе code-behind. Это очень просто, но некоторые могут утверждать, что в XAML неясно, куда указывает DataContext.
- Путем установки
DataContext
в XAML с использованием DataBinding
Самый простой и, я думаю, самый элегантный способ установить DataContext на уровне Window / UserControl в XAML очень прост; просто добавьте DataContext="{Binding RelativeSource={RelativeSource Self}}"
к вашему Window
элементу. RelativeSource Self
просто означает «привязать непосредственно к объекту», который в данном случае является Window
объектом. Отсутствие свойства Path
приводит к значению по умолчанию Path
, которым является сам исходный объект (т.е. окно).
<Window x:Class="MyProject.Form1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<CheckBox ...
IsChecked="{Binding ShowPending}">
</CheckBox>
</Grid>
</Window>
Как только вы это сделаете, свойство DataContext
для всех дочерних элементов управления станет классом Window
, поэтому привязка данных к свойствам в вашем коде будет естественной.
Если по какой-то причине вы не хотите устанавливать DataContext
в Окне, но хотите установить его ниже по иерархии управления, то вы можете сделать это, используя механизм FindAncestor
. Например. если вы хотите установить его для элемента Grid и всех дочерних элементов Grid:
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
<CheckBox ...
IsChecked="{Binding ShowPending}">
</CheckBox>
</Grid>
Вероятно, стоит отметить, что на данный момент мы достигли возможности привязать элемент управления пользовательского интерфейса к свойству класса code-behind и поддерживать это свойство code-behind в актуальном состоянии. с изменениями в элементе пользовательского интерфейса. Поэтому, если пользователь проверяет CheckBox, свойство ShowPending
будет обновлено.
Но довольно часто вы также хотите, чтобы обратное было правдой; изменение свойства источника должно быть отражено в соответствующем изменении элемента управления пользовательского интерфейса. Это можно увидеть, добавив другой элемент управления CheckBox в ваше окно, привязанное к тому же свойству ShowPending
. Когда вы нажимаете один флажок, вы, вероятно, надеетесь или ожидаете, что другой флажок будет синхронизирован, но этого не произойдет. Чтобы достичь этого, ваш класс code-behind должен либо (a) реализовать INotifyPropertyChanged
, (b) добавить событие ShowPendingChanged
или (c) сделать ShowPending
a Свойство зависимости, Из 3 я предлагаю реализовать INotifyPropertryChanged
в вашем коде позади - самый распространенный механизм.