RelativeSource のマークアップ拡張機能

Binding マークアップ拡張内で使用されるか、または XAML で設定された Binding 要素の RelativeSource プロパティの設定時に使用される、RelativeSource バインディング ソースのプロパティを指定します。

XAML 属性の使用方法

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

XAML 属性の使用方法 (バインディング拡張内で入れ子にした場合)

<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 値

説明
modeEnumValue 次のいずれか:

- 文字列トークン SelfRelativeSource に対応し、Mode プロパティは Self に設定されます。
- 文字列トークン TemplatedParentRelativeSource に対応し、Mode プロパティは TemplatedParent に設定されます。
- 文字列トークン PreviousDataRelativeSource に対応し、Mode プロパティは PreviousData に設定されます。
- FindAncestor モードについては後の説明を参照してください。
FindAncestor 文字列トークン FindAncestor。 このトークンを使用すると、RelativeSource によって先祖の型およびオプションで先祖レベルを指定するモードになります。 これは、RelativeSource プロパティが Mode に設定された状態で作成された FindAncestor に対応します。
typeName FindAncestor モードで必要です。 AncestorType プロパティに指定する型の名前。
intLevel FindAncestor モードのオプションです。 論理ツリー内で親の方向に向けて数えた先祖レベル。

Remarks

{RelativeSource TemplatedParent} バインディングの用法は、コントロールの UI とロジックを分離するという、より大きな構想を解決するための鍵となる手法です。 これによって、テンプレートが適用される親 (テンプレートが適用されるランタイム オブジェクト インスタンス) へのバインディングをテンプレート定義内から行うことができます。 この場合、TemplateBinding マークアップ拡張は実際には、バインディング式 {Binding RelativeSource={RelativeSource TemplatedParent}} の短縮形です。 TemplateBinding または {RelativeSource TemplatedParent} の使用方法はどちらも、テンプレートを定義する XAML 内でのみ意味を持ちます。 詳細については、「TemplateBinding のマークアップ拡張機能」を参照してください。

{RelativeSource FindAncestor} の主な用途は、コントロール テンプレート内または予測可能な独立した UI 合成です。特定の先祖の型のビジュアル ツリー内にコントロールが常に存在することがわかっているケースで使用されます。 たとえば、項目コントロールの各項目は FindAncestor を使用して、その項目コントロールの親先祖のプロパティにバインドすることができます。 または、テンプレート内のコントロール合成に参加している要素は、同じ合成体系の親要素に対して FindAncestor バインディングを使用できます。

XAML 構文のセクションに示した FindAncestor モードのオブジェクト要素構文では、2 番目のオブジェクト要素構文は FindAncestor モード向けに使用されます。 FindAncestor モードでは、AncestorType 値が必要です。 検索する先祖の型への x:Type マークアップ拡張参照を使用して、AncestorType を属性として設定する必要があります。 AncestorType 値は、実行時にバインディング要求を処理する際に使用されます。

FindAncestor モードでは、オプションの AncestorLevel プロパティは、要素ツリー内に型の先祖が複数存在する可能性がある場合に、先祖の検索のあいまいさを解消するのに役立ちます。

FindAncestor モードの使用方法の詳細については、「RelativeSource」を参照してください。

{RelativeSource Self} は、特定のインスタンスのプロパティが同じインスタンスの別のプロパティの値に依存しており、その 2 つのプロパティ間に通常の依存関係プロパティの関係 (強制変換など) が存在しない状況で使用できます。 まったく同じ値、まったく同じ型を持つ 2 つのプロパティが 1 つのオブジェクトに存在することはまれですが、{RelativeSource Self} を持つバインディングに Converter パラメーターを適用し、そのコンバーターを使用してソースとターゲットの型変換を行うこともできます。 {RelativeSource Self} は、MultiDataTrigger の一部として使用することもできます。

たとえば、Rectangle という XAML は、Width 要素を定義します。Rectangle にどのような値が入力されても、<Rectangle Width="200" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}" .../> は常に正方形となります。

{RelativeSource PreviousData} は、データ テンプレートで使用できるほか、バインディングにデータ ソースのコレクションを使用する場合にも役立ちます。 {RelativeSource PreviousData} を使用すると、コレクション内の隣接するデータ項目どうしの関係に注目することができます。 これと関連して、データ ソース内の現在の項目と直前の項目との間に MultiBinding を確立し、そのバインディング上のコンバーターを使用して、2 つの項目 (およびそれらのプロパティ) 間の相違を特定する手法もあります。

次の例の項目テンプレートに出現する 1 つ目の TextBlock は、現在の数値を表示します。 2 つ目の TextBlock バインディングは MultiBinding で、通常 2 つの 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>

ここで説明されていないデータ バインディングの概念については、データ バインディングの概要に関する記事を参照してください。

WPF の XAML プロセッサの実装では、このマークアップ拡張の処理は RelativeSource クラスによって定義されています。

RelativeSource はマークアップ拡張機能です。 一般にマークアップ拡張機能を実装するのは、属性値をリテラル値やハンドラー名以外にエスケープする要件が存在し、その要件の適用範囲がグローバルで、特定の型やプロパティに型コンバーターを適用するだけにとどまらない場合です。 XAML のすべてのマークアップ拡張では、それぞれの属性構文で {} の 2 つの記号が使用されます。これは規約であり、これに従って XAML プロセッサでは、マークアップ拡張で属性を処理する必要があることが認識されます。 詳細については、「マークアップ拡張機能と WPF XAML」を参照してください。

関連項目