{x:Bind} マークアップ拡張

{x:Bind} によりアプリでデータ バインディングを使用する方法に関する一般的な情報 (および {x:Bind}{Binding} の全体的な比較) については、「データ バインディングの詳細」をご覧ください。

{x:Bind}マークアップ拡張機能 (Windows 10 の新機能) は、{Binding}の代わりに使用できます。 {x:Bind} は、{Binding} よりも短い時間および少ないメモリで動作し、より適切なデバッグをサポートしています。

XAML コンパイル時に、 {x:Bind} は、データ ソースのプロパティから値を取得し、マークアップで指定されたプロパティに設定するコードに変換されます。 必要に応じて、データ ソース プロパティの値の変更を観察し、それらの変更 (Mode="OneWay") に基づいて自身を更新するようにバインディング オブジェクトを構成できます。 必要に応じて、独自の値の変更をソース プロパティ (Mode="TwoWay") にプッシュするように構成することもできます。

{x:Bind}{Binding} によって作成されたバインド オブジェクトは、ほとんど機能的に同等です。 ただし、 {x:Bind} はコンパイル時に生成される特殊な目的のコードを実行し、 {Binding} は汎用ランタイム オブジェクト検査を使用します。 したがって、 {x:Bind} バインド (コンパイル済みバインドと呼ばれることが多い) は、優れたパフォーマンスを発揮し、バインド式のコンパイル時検証を提供し、ページの部分クラスとして生成されるコード ファイルにブレークポイントを設定できるようにすることでデバッグをサポートします。 これらのファイルは obj フォルダー内にあり、<view name>.g.cs (C# の場合) などの名前が付けられています。

ヒント

{x:Bind}には、{Binding} とは異なり、OneTimeの既定のモードOneWay。 これはパフォーマンス上の理由から選ばれました。OneWay を使うと、接続して変更検出を処理するために生成されるコードが多くなるためです。 OneWay または TwoWay バインドを使用するモードを明示的に指定できます。 x:DefaultBindMode を使用して、マークアップ ツリーの特定のセグメントの{x:Bind}の既定のモードを変更することもできます。 指定したモードは、バインドの一部としてモードを明示的に指定しない、その要素とその子に対する {x:Bind} 式に適用されます。

{x:Bind} の使い方を示すサンプル アプリ

XAML 属性の使用方法

<object property="{x:Bind}" .../>
-or-
<object property="{x:Bind propertyPath}" .../>
-or-
<object property="{x:Bind bindingProperties}" .../>
-or-
<object property="{x:Bind propertyPath, bindingProperties}" .../>
-or-
<object property="{x:Bind pathToFunction.functionName(functionParameter1, functionParameter2, ...), bindingProperties}" .../>
項目 説明
propertyPath バインドのプロパティ パスを指定する文字列。 詳しくは、以下の「プロパティ パス」をご覧ください。
bindingProperties
propName=value[, propName=value]* 名前と値のペアの構文を使って指定する、1 つ以上のバインド プロパティ。
propName バインド オブジェクトに設定するプロパティの文字列名。 たとえば、"Converter" です。
value プロパティに設定する値。 引数の構文は、設定されているプロパティによって異なります。 値自体がマークアップ拡張である propName=value 使用法の例を次に示 Converter={StaticResource myConverterClass}。 詳細については、以下の「{x:Bind} セクションで設定できる Properties」を参照してください。

<Page x:Class="QuizGame.View.HostView" ... >
    <Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Page>

この XAML の例では、ListView.ItemTemplate プロパティと共に {x:Bind}を使用します。 x:DataType 値の宣言に注意してください。

  <DataTemplate x:Key="SimpleItemTemplate" x:DataType="data:SampleDataGroup">
    <StackPanel Orientation="Vertical" Height="50">
      <TextBlock Text="{x:Bind Title}"/>
      <TextBlock Text="{x:Bind Description}"/>
    </StackPanel>
  </DataTemplate>

[プロパティのパス]

PropertyPath{x:Bind}式のPathを設定します。 Path は、バインド先のプロパティ、サブプロパティ、フィールド、またはメソッド (ソース) の値を指定するプロパティ パスです。 Path プロパティの名前を明示的に指定できます:{x:Bind Path=...}。 または、省略できます: {x:Bind ...}

プロパティ パスの解決

{x:Bind} では、既定のソースとして DataContext を使用しません。代わりに、ページコントロールまたはユーザー コントロール自体が使用されます。 そのため、ページまたはユーザー コントロールの分離コードで、プロパティ、フィールド、およびメソッドを確認します。 ビュー モデルを {x:Bind}に公開するには、通常、ページまたはユーザー コントロールの分離コードに新しいフィールドまたはプロパティを追加します。 プロパティ パスのステップは、ドット (.) で区切ります。複数の区切り記号を指定することで、連続するサブプロパティを走査できます。 バインドされているオブジェクトを実装するために使用するプログラミング言語に関係なく、ドット区切り記号を使います。

たとえば、ページ内で、Text="{x:Bind Employee.FirstName}" は、ページ上で Employee メンバーを検索し、その後、Employee によって返されるオブジェクトの FirstName メンバーを検索します。 従業員の扶養家族を含むプロパティに項目コントロールをバインドする場合、プロパティ パスは "Employee.Dependents" となり、"Dependents" の項目の表示には項目コントロールの項目テンプレートが使われます。

C++/CX の場合、 {x:Bind} ページまたはデータ モデルのプライベート フィールドとプロパティにバインドできません。バインド可能にするにはパブリック プロパティが必要です。 関連するメタデータを取得できるように、バインディングのサーフェス領域を CX クラス/インターフェイスとして公開する必要があります。 [Bindable] 属性は必要ありません。

x:Bind では、バインド式の一部として ElementName=xxx を使用する必要はありません。 代わりに、要素の名前をバインディングのパスの先頭部分として使用できます。これは、名前付き要素が、ルート バインディング ソースを表すページまたはユーザー コントロール内のフィールドになるためです。

コレクション

データ ソースがコレクションである場合、プロパティ パスには、位置またはインデックスによりコレクション内の項目を指定できます。 たとえば "Teams[0].Players" では、"0" をリテラル "[]" で囲むことで、インデックス 0 で始まるコレクション内の最初の項目を要求します。

インデクサーを使用するには、インデックスを作成するプロパティの型に IList<T> または IVector<T> を実装する必要があります。 (IReadOnlyList に注意してください<T> および IVectorView<T> はインデクサー構文をサポートしていません。インデックス付きプロパティの型が INotifyCollectionChanged または IObservableVector バインディングが OneWay または TwoWay である場合は、それらのインターフェイスで変更通知を登録してリッスンします。 変更検出ロジックは、特定のインデックス付き値に影響を与えない場合でも、すべてのコレクションの変更に基づいて更新されます。 これは、リッスン ロジックがコレクションのすべてのインスタンスで共通であるためです。

データ ソースが Dictionary または Map の場合、プロパティ パスは文字列名でコレクション内の項目を指定できます。 たとえば、<TextBlock Text="{x:Bind Players['John Smith']}" /> と指定すると、ディクショナリで "John Smith" という名前の項目が検索されます。 名前は引用符で囲む必要があり、単一引用符または二重引用符を使用できます。 Hat (^) を使用すると、文字列内の引用符をエスケープできます。 XAML 属性に使用されるものから代替引用符を使用するのが最も簡単です。 (IReadOnlyDictionary<T> と IMapView<T> はインデクサー構文には対応していないのでご注意ください。)

文字列インデクサーを使用するには、インデックスを作成するプロパティの型に IDictionary<string、T> または IMap<string、T> を実装する必要があります。 インデックス付きプロパティの型が IObservableMap をサポートしていて、バインディングが OneWay または TwoWay の場合、それらのインターフェイスで変更通知を登録してリッスンします。 変更検出ロジックは、特定のインデックス付き値に影響を与えない場合でも、すべてのコレクションの変更に基づいて更新されます。 これは、リッスン ロジックがコレクションのすべてのインスタンスで共通であるためです。

関連付けられたプロパティ

添付プロパティにバインドするには、クラスおよびプロパティ名をドットの後のかっこ内に含める必要があります。 たとえば、 Text="{x:Bind Button22.(Grid.Row)}"。 プロパティが Xaml 名前空間で宣言されていない場合は、xml 名前空間のプレフィックスを付ける必要があります。この名前空間は、ドキュメントの先頭にあるコード名前空間にマップする必要があります。

キャスト

コンパイルされたバインドは厳密に型指定され、パス内の各ステップの型が解決されます。 返された型にメンバーがない場合、コンパイル時に失敗します。 キャストを指定して、オブジェクトの実際の型をバインドするように指定できます。

次の場合、 obj はオブジェクト型のプロパティですが、テキスト ボックスが含まれているため、 Text="{x:Bind ((TextBox)obj) を使用できます。Text}" または Text="{x:Bind obj.(TextBox.Text)}"

Text="{x:Bind ((data:SampleDataGroup)groups3[0]).Title}"groups3 フィールドは、オブジェクトのディクショナリです。したがって、data:SampleDataGroup にキャストする必要があります。 既定の XAML 名前空間の一部ではないコード名前空間にオブジェクト型をマッピングするための xml data: 名前空間プレフィックスの使用に注意してください。

注: C#スタイルのキャスト構文は、添付プロパティ構文よりも柔軟性が高く、今後推奨される構文です。

パスを使用しないキャスト

ネイティブ バインド パーサーには、this を関数パラメーターとして表すキーワードはありませんが、関数パラメーターとして使用できるパスを使用しないキャスト (例: {x:Bind (x:String)}) に対応しています。 したがって、{x:Bind MethodName(this)} と概念的に同等なことを実行するのに、{x:Bind MethodName((namespace:TypeOfThis))} は有効な方法です。

例:

Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}"

<Page
    x:Class="AppSample.MainPage"
    ...
    xmlns:local="using:AppSample">

    <Grid>
        <ListView ItemsSource="{x:Bind Songs}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:SongItem">
                    <TextBlock
                        Margin="12"
                        FontSize="40"
                        Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>
namespace AppSample
{
    public class SongItem
    {
        public string TrackName { get; private set; }
        public string ArtistName { get; private set; }

        public SongItem(string trackName, string artistName)
        {
            ArtistName = artistName;
            TrackName = trackName;
        }
    }

    public sealed partial class MainPage : Page
    {
        public List<SongItem> Songs { get; }
        public MainPage()
        {
            Songs = new List<SongItem>()
            {
                new SongItem("Track 1", "Artist 1"),
                new SongItem("Track 2", "Artist 2"),
                new SongItem("Track 3", "Artist 3")
            };

            this.InitializeComponent();
        }

        public static string GenerateSongTitle(SongItem song)
        {
            return $"{song.TrackName} - {song.ArtistName}";
        }
    }
}

バインド パス内の関数

Windows 10 バージョン 1607 以降、{x:Bind} はバインド パスのリーフ ステップとしての関数の使用をサポートします。 これはデータバインディングにとって強力な機能であり、マークアップにおいて複数のシナリオを可能にします。 詳しくは、関数バインドに関する記事をご覧ください。

イベント バインド

イベント バインディングは、コンパイル済みバインドの一意の機能です。 これにより、分離コードのメソッドである必要はなく、バインディングを使用してイベントのハンドラーを指定できます。 例: Click="{x:Bind rootFrame.GoForward}"

イベントの場合、ターゲット メソッドをオーバーロードする必要はありません。また、次のことも行う必要があります。

  • イベントのシグネチャと一致します。
  • またはパラメーターがありません。
  • または、イベント パラメーターの型から割り当て可能な型のパラメーターの数が同じです。

生成された分離コードでは、コンパイルされたバインドによってイベントが処理され、モデル上のメソッドにルーティングされ、イベントが発生したときにバインディング式のパスが評価されます。 つまり、プロパティ バインドとは異なり、モデルへの変更は追跡されません。

プロパティ パスの文字列構文の詳細については、「<Property-path 構文{x:Bind}に関してここで説明されている相違点に留意してください。

{x:Bind} で設定できるプロパティ

{x:Bind} は、マークアップ拡張機能で設定できる複数の読み取り/書き込みプロパティがあるため、 bindingProperties プレースホルダー構文で示されています。 プロパティは、propName=value ペアをコンマで区切ることにより、任意の順序で設定できます。 バインド式に改行を含めることはできません。 一部のプロパティには型変換がない型が必要であるため、 {x:Bind}内で入れ子になった独自のマークアップ拡張が必要です。

これらのプロパティは、 Binding クラスのプロパティとほぼ同じように動作します。

プロパティ 説明
Path 上記の「プロパティ パス」をご覧ください。
Converter バインディング エンジンによって呼び出されるコンバーター オブジェクトを指定します。 コンバーターは XAML で設定できますが、 {StaticResource} マークアップ拡張で割り当てたオブジェクト インスタンスを参照する場合にのみ リソース ディクショナリ内のそのオブジェクトを参照します。
ConverterLanguage コンバーターで使うカルチャを指定します (を設定している場合ConverterLanguageConverterも設定する必要があります。カルチャは標準ベースの識別子として設定されます。 詳細については、「 ConverterLanguageを参照してください。
ConverterParameter コンバーター ロジックで使用できるコンバーター パラメーターを指定します。 (を設定している場合ConverterParameterConverterも設定する必要があります。ほとんどのコンバーターは、渡された値から必要なすべての情報を取得して変換する単純なロジックを使用し、ConverterParameter 値は必要ありません。 ConverterParameter パラメーターは、ConverterParameterで渡された内容をキーオフする複数のロジックを持つ、中程度に高度なコンバーター実装用です。 また、文字列以外の値を使うコンバーターも作成できますが、一般的ではありません。詳しくは、「ConverterParameter」の「注釈」をご覧ください。
FallbackValue ソースまたはパスを解決できない場合に表示する値を指定します。
Mode バインド モードを、"OneTime"、"OneWay"、または "TwoWay" のいずれかの文字列として指定します。 既定値は "OneTime" です。 これは、 {Binding}の既定値 (ほとんどの場合は "OneWay") とは異なります。
TargetNullValue ソース値が解決されるが、明示的に null である場合に表示する値を設定します。
BindBack 双方向バインディングの逆方向に使用する関数を指定します。
UpdateSourceTrigger TwoWay バインドでコントロールからモデルに変更をプッシュバックするタイミングを指定します。 TextBox.Text を除くすべてのプロパティの既定値は PropertyChanged です (TextBox.Text は LostFocus)。

Note

マークアップを {Binding} から {x:Bind}に変換する場合は、 Mode プロパティの既定値の違いに注意してください。 x:DefaultBindMode を使用して、マークアップ ツリーの特定のセグメントの x:Bind の既定のモードを変更できます。 選択したモードは、バインドの一部としてモードを明示的に指定しない、その要素とその子に x:Bind 式を適用します。 OneWay を使用すると、変更検出をフックアップして処理するために生成されるコードが増えるので、OneTime の方が OneWay よりもパフォーマンスが高くなります。

解説

{x:Bind}は生成されたコードを使用してその利点を実現するため、コンパイル時に型情報が必要です。 これは、型が事前にわからないプロパティにバインドできないことを意味します。 このため、 {x:Bind} は、 DataContext プロパティ ( Object 型であり、実行時にも変更される可能性があります。

{x:Bind} をデータ テンプレートと共に使用するときは、「」のセクションに示すように、x:DataType 値を設定し、バインド先の型を指定する必要があります。 また、型をインターフェイスまたは基底クラスの型に設定し、必要に応じてキャストを使用して完全な式を作成することもできます。

コンパイルされたバインドは、コードの生成によって異なります。 そのため、リソース ディクショナリで {x:Bind} を使用する場合、リソース ディクショナリには分離コード クラスが必要です。 コード例については、{x:Bind} を使用した Resource ディクショナリを参照してください。

コンパイル済みバインドを含むページとユーザー コントロールには、生成されたコードに "Bindings" プロパティが含まれます。 これには次のメソッドが含まれます。

  • Update() - これにより、コンパイルされたすべてのバインディングの値が更新されます。 一方向/双方向バインディングでは、変更を検出するためにリスナーがフックされます。
  • Initialize() - バインドがまだ初期化されていない場合は、Update() を呼び出してバインディングを初期化します
  • StopTracking() - これにより、一方向と双方向のバインド用に作成されたすべてのリスナーのフックが解除されます。 これらは、Update() メソッドを使用して再初期化できます。

Note

Windows 10、バージョン1607 以降では、XAML フレームワークにブール値と Visibility 値のコンバーターが組み込まれています。 コンバーターは、Visible 列挙値に対して true を、Collapsed に対して false をマッピングします。これにより、コンバーターを作成せずに Visibility プロパティをブール値にバインドできます。 これは関数バインドの機能ではなく、プロパティ バインドのみであることに注意してください。 組み込みのコンバーターを使用するには、アプリの最小のターゲット SDK バージョンが 14393 以降である必要があります。 アプリがそれよりも前のバージョンの Windows 10 をターゲットとしている場合は使うことができません。 ターゲット バージョンについて詳しくは、「バージョン アダプティブ コード」をご覧ください。

ヒント: PathConverterParameter のように、値に 1 つの中かっこを指定する必要がある場合は、\{ のように円記号 (バックスラッシュ) を中かっこの前に付けます。 別の方法として、エスケープする必要がある中かっこを含む文字列全体を ConverterParameter='{Mix}' のように別の種類の引用符で囲みます。

ConverterConverterLanguageConverterLanguage はいずれも、バインド ソースの値または型を、バインディング ターゲットのプロパティと互換性のある型または値に変換するシナリオに関係があります。 例や詳しい情報については、「データ バインディングの詳細」の「データの変換」をご覧ください。

{x:Bind} はマークアップ拡張機能のみであり、そのようなバインディングをプログラムで作成または操作する方法はありません。 マークアップ拡張機能の詳細については、 XAML の概要を参照してください。