Расширение разметки {RelativeSource}

Предоставляет способ указания источника привязки в терминах относительной связи внутри графа объекта среды выполнения.

Использование атрибута языка XAML (режим Self)

<Binding RelativeSource="{RelativeSource Self}" .../>
-or-
<object property="{Binding RelativeSource={RelativeSource Self} ...}" .../>

Использование атрибута языка XAML (узел TemplatedParent)

<Binding RelativeSource="{RelativeSource TemplatedParent}" .../>
-or-
<object property="{Binding RelativeSource={RelativeSource TemplatedParent} ...}" .../>

Значения XAML

Термин Описание
{RelativeSource Self} Создает значение Mode для Self. В качестве источника этой привязки следует использовать целевой элемент. Это полезно для привязки одного из свойств элемента к другому свойству того же элемента.
{RelativeSource TemplatedParent} Создает элемент ControlTemplate, который служит источником этой привязки. Это полезно для применения информации времени выполнения к привязкам на уровне шаблонов.

Комментарии

Класс Binding может задать Binding.RelativeSource как атрибут элемента объекта Binding или как компонент в расширении разметки {Binding}. Именно по этой причине отображаются два различных синтаксиса XAML.

RelativeSource аналогичен расширению разметки {Binding}. Схожесть заключается в том, что расширение разметки может возвращать свои экземпляры, поддерживая конструкцию на основе строки, которая, таким образом, передает аргумент конструктору. В этом случае передаваемый аргумент — это значение Mode.

Режим Self полезен для привязки одного свойства элемента к другому свойству того же элемента; это вариант привязки ElementName, не требующей именования элемента и установки для него ссылки на себя самого. Если нужно привязать одно свойство элемента к другому свойству того же элемента, эти свойства либо должны быть одного типа, либо на их привязке необходимо использовать Converter для преобразования значений. Например, можно использовать Height как источник для Width без преобразования, но чтобы использовать IsEnabled в качестве источника для Visibility, понадобится преобразователь.

Пример приведен ниже. Rectangle использует расширение разметки {Binding}, чтобы значения Height и Width всегда были равны и при отрисовке отображался квадрат. Только значение Height является фиксированным. Для этого объекта Rectangle значение DataContext по умолчанию равно null, а не this. Таким образом, чтобы установить источник контекста данных как объект (и включить привязку к другим его свойствам), используется аргумент RelativeSource={RelativeSource Self} в качестве расширения разметки {Binding}.

<Rectangle
  Fill="Orange" Width="200"
  Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}"
/>

Также RelativeSource={RelativeSource Self} можно использовать, чтобы задать для свойства DataContext объекта самого себя. Например, этот метод можно увидеть в некоторых примерах пакета SDK, где класс Page был расширен с помощью настраиваемого свойства, которое уже предоставляет готовую модель представления для собственной привязки данных, например: <common:LayoutAwarePage ... DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}">

Примечание Использование XAML для RelativeSource показывает только использование, для которого он предназначен: установка значения для Binding.RelativeSource в XAML в составе выражения привязки. Теоретически возможны и другие способы задания свойства, значением которого является RelativeSource.