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

Задает свойства источника привязки RelativeSource для использования внутри расширения разметки привязки или при задании свойства RelativeSource элемента Binding, определенного в XAML.

Использование атрибута XAML

<Binding RelativeSource="{RelativeSource modeEnumValue}" ... />

Использование атрибута XAML (вложенный в расширение Binding)

<object property="{Binding RelativeSource={RelativeSource modeEnumValue} ...}" ... />

Использование элемента объекта XAML

<Binding>
  <Binding.RelativeSource>
    <RelativeSource Mode="modeEnumValue"/>
  </Binding.RelativeSource>
</Binding>

или

<Binding>
  <Binding.RelativeSource>
    <RelativeSource
      Mode="FindAncestor"
      AncestorType="{x:Type typeName}"
      AncestorLevel="intLevel"
    />
  </Binding.RelativeSource>
</Binding>

Значения XAML

Стоимость Description
modeEnumValue Один из следующих:

- Строковая лексема Self; соответствует RelativeSource при создании со свойством Mode, для которого установлено значение Self.
- Строковая лексема TemplatedParent; соответствует RelativeSource при создании со свойством Mode, для которого установлено значение TemplatedParent.
- Строковая лексема PreviousData; соответствует RelativeSource при создании со свойством Mode, для которого установлено значение PreviousData.
- Сведения о режиме FindAncestor приведены ниже.
FindAncestor Строковая лексема FindAncestor. Использовании этой лексемы осуществляет переход в режим, где RelativeSource задает тип предка и (при необходимости) уровень предка. Это соответствует RelativeSource при создании со свойством Mode, для которого задано значение FindAncestor.
typeName Требуется для режима FindAncestor. Имя типа, которое заполняет свойство AncestorType.
intLevel Необязательно для режима FindAncestor. Уровень предка (вычисляется в направлении родителя в логическом дереве).

Замечания

Использование привязки {RelativeSource TemplatedParent} является основным механизмом решения масштабной задачи разделения пользовательского интерфейса элемента управления и логики элемента управления. Это делает возможным привязку из определения шаблона к созданному по шаблону родительскому элементу (экземпляр объекта времени выполнения, в котором применяется шаблон). В этом случае расширение разметки TemplateBinding фактически является сокращением для следующего выражения привязки: {Binding RelativeSource={RelativeSource TemplatedParent}}. Использование TemplateBinding или {RelativeSource TemplatedParent} имеет значение только в коде XAML, который определяет шаблон. Дополнительные сведения см. в разделе Расширение разметки TemplateBinding.

{RelativeSource FindAncestor} используется главным образом в шаблонах элементов управления или предсказуемых автономных композициях пользовательского интерфейса в случаях, когда элемент управления всегда должен находиться в видимом дереве определенного типа предка. Например, элементы в элементе управления элементами могут использовать вхождения FindAncestor для привязки к свойствам предка элемента управления элементами. Либо элементы, которые являются частью композиции элемента управления в шаблоне, могут использовать привязки FindAncestor к родительским элементам в той же структуре композиции.

В синтаксисе объектного элемента для режима FindAncestor, показанного выше в разделах синтаксиса XAML, второй синтаксис объектного элемента используется специально для режима FindAncestor. Режим FindAncestor требует значения AncestorType. AncestorType необходимо установить в качестве атрибута, используя ссылку расширение разметки x:Type на тип искомого предка. Значение AncestorType используется при обработке запроса привязки во время выполнения.

Для режима FindAncestor необязательное свойство AncestorLevel может помочь устранить неоднозначность поиска предка в случаях, где в дереве элементов, возможно, существует более одного предка данного типа.

Дополнительные сведения об использовании режима FindAncestor см. в разделе RelativeSource.

{RelativeSource Self} удобно использовать в сценариях, где одно из свойств экземпляра должно зависеть от значения другого свойства того же экземпляра, но между этими двумя свойствами еще не существует общего отношения свойства зависимостей, такого как приведение. Хотя изредка случается так, что в объекте существует два свойства с буквально одинаковыми значениями (и идентичными типами), также можно применить параметр Converter к привязке с {RelativeSource Self} и использовать преобразователь для преобразования из исходного типа в целевой. Еще один сценарий использования {RelativeSource Self} — в составе MultiDataTrigger.

Например, следующий код XAML определяет такой элемент Rectangle, что независимо от того, какое значение вводится для свойства Width, объектом Rectangle всегда является квадрат: <Rectangle Width="200" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}" .../>

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

В следующем примере первый элемент TextBlock в шаблоне элементов отображает текущий номер. Вторая привязка TextBlock является привязкой MultiBinding, которая номинально состоит из двух частей Binding: текущей записи и привязки, в которой намеренно используется предыдущая запись данных с помощью {RelativeSource PreviousData}. Затем преобразователь в объекте MultiBinding вычисляет разницу и возвращает ее в привязку.

<ListBox Name="fibolist">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding}"/>
            <TextBlock>, difference = </TextBlock>
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding Converter="{StaticResource DiffConverter}">
                            <Binding/>
                            <Binding RelativeSource="{RelativeSource PreviousData}"/>
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Описание принципа привязки данных не рассматривается в данном разделе; см. раздел Общие сведения о привязке данных.

В реализации обработчика XAML WPF обработка данного расширения разметки определяется классом RelativeSource.

RelativeSource является расширением разметки. Расширения разметки обычно реализуются, если требуется заменить значения атрибутов на нелитеральные значения или имена обработчиков и если требуется больше, чем простая настройка преобразователей типов на работу с определенными типами или свойствами. Все расширения разметки в XAML используют символы { и } в синтаксисе их атрибутов, который является соглашением, по которому обработчик XAML узнает, что расширение разметки должно обработать атрибут. Дополнительные сведения см. в разделе Расширения разметки и XAML WPF.

См. также