基本的なバインディング

サンプルを参照します。 サンプルを参照する

.NET Multi-platform App UI (.NET MAUI) のデータ バインディングでは、通常は少なくとも一方がユーザー インターフェイス オブジェクトである 2 つのオブジェクト間において、プロパティのペアをリンクします。 これら 2 つのオブジェクトは、"ターゲット" および "ソース" と呼ばれます。

  • "ターゲット" は、データ バインディングが設定されている方のオブジェクト (およびプロパティ) です。
  • "ソース" は、データ バインディングによって参照されている方のオブジェクト (およびプロパティ) です。

最も単純な場合は、データがソースからターゲットに流れます。これは、ソース プロパティの値からターゲット プロパティの値が設定されることを意味します。 ただし、場合によっては、データがターゲットからソースに、または双方向に流れることがあります。

重要

データを受け取るのではなくデータを提供する場合でも、ターゲットは常に、データ バインディングが設定されたオブジェクトになります。

バインディング コンテキストを使用したバインド

次の XAML の例を考えてみましょう。その目的は、Slider を操作して Label を回転させることです。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="Center" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

データ バインディングを使用しない場合は、SliderValueChanged イベントを、SliderValue プロパティにアクセスしてその値を LabelRotation プロパティに設定するイベント ハンドラーに設定します。 データ バインディングによってこのタスクが自動化されるため、イベント ハンドラーとイベント ハンドラー内のコードは不要になります。

BindableObject から派生した任意のクラスのインスタンスにバインディングを設定できます。これには、ElementVisualElementViewView の派生クラスが含まれます。 バインディングは、常にターゲット オブジェクトに設定されます。 そのバインディングによって、ソース オブジェクトが参照されます。 データ バインディングを設定するには、次に示すターゲット クラスの 2 つのメンバーを使用します。

  • BindingContext プロパティでは、ソース オブジェクトを指定します。
  • SetBinding メソッドでは、ターゲット プロパティとソース プロパティを指定します。

この例では、Label がバインディング ターゲットで、Slider がバインディング ソースです。 Slider ソースにおける変更が、Label テンプレートの回転に影響を与えます。 データはソースからターゲットに流れます。

BindableObject によって定義された SetBinding メソッドには、Binding クラスの派生元となる BindingBase 型の引数が使用されていますが、BindableObjectExtensions クラスによって定義された他の SetBinding メソッドがあります。 XAML の分離コードでは、BindableObjectExtensions クラスのより単純な SetBinding 拡張メソッドが使用されます。

public partial class BasicCodeBindingPage : ContentPage
{
    public BasicCodeBindingPage()
    {
        InitializeComponent();

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

Label オブジェクトはバインディング ターゲットです。したがって、このプロパティが設定されるオブジェクトであり、メソッドが呼び出される対象のオブジェクトです。 BindingContext プロパティでは、バインディング ソースである Slider が示されています。 SetBinding メソッドはバインディング ターゲットに対して呼び出されますが、ターゲット プロパティとソース プロパティの両方を指定しています。 ターゲット プロパティである Label.RotationProperty は、BindableProperty オブジェクトとして指定されています。 ソース プロパティは文字列として指定され、SliderValue プロパティを示しています。

重要

ターゲット プロパティは、バインド可能なプロパティによってサポートされている必要があります。 したがって、ターゲット オブジェクトは BindableObject から派生したクラスのインスタンスである必要があります。 詳細については、「バインド可能プロパティ」をご覧ください。

ソースプロパティは文字列として指定されます。 内部的には、実際のプロパティにアクセスするためにリフレクションが使用されます。 ただし、この特定のケースでは、Value プロパティはバインド可能なプロパティによってもサポートされています。

Slider を操作すると、それに応じて Label が回転します。

基本的なコード バインディング

または、XAML でデータ バインディングを指定することもできます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

コードの場合と同様、ターゲット オブジェクトである Label にデータ バインディングを設定しています。 データ バインディングの定義には、次の 2 つの XAML マークアップ拡張機能が使用されます。

  • x:Reference マークアップ拡張は、slider という名前の Slider であるソース オブジェクトを参照するために必要です。
  • Binding マークアップ拡張によって、LabelRotation プロパティが、SliderValue プロパティにリンクされます。

XAML マークアップ拡張機能の詳細については、「XAML マークアップ拡張機能を使用する」をご覧ください。

Note

ソース プロパティは Binding マークアップ拡張機能の Path プロパティで指定され、これは Binding クラスの Path プロパティに対応します。

x:ReferenceBinding などの XAML マークアップ拡張には、コンテンツ プロパティ属性を定義することができます。これは、XAML マークアップ拡張に対してプロパティ名を使用する必要がないことを意味します。 Name プロパティは x:Reference のコンテンツ プロパティであり、Path プロパティは Binding のコンテンツ プロパティです。つまり、これらは式から省略できます。

<Label Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="Center"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

重要

バインドのパフォーマンスは、コンパイル済みのバインドを使用して向上させることができます。 詳しくは、「コンパイル済みのバインド」を参照してください。

バインディング コンテキストを使用しないバインド

BindingContext プロパティは、データ バインディングの重要なコンポーネントですが、常に必要なわけではありません。 代わりに SetBinding 呼び出しまたは Binding マークアップ拡張機能でソース オブジェクトを指定できます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

この例では、SliderLabelScale プロパティを制御するように定義されています。 そのため、Slider は -2 から 2 までの範囲に設定されています。

分離コード ファイルは、SetBinding メソッドとのバインドを設定します。2 番目の引数は Binding クラスのコンストラクターです。

public partial class AlternativeCodeBindingPage : ContentPage
{
    public AlternativeCodeBindingPage()
    {
        InitializeComponent();

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

Binding コンストラクターには 6 つのパラメーターがあるため、名前付き引数を使用して source パラメーターが指定されています。 その引数は slider オブジェクトです。

Note

VisualElement クラスでは、ScaleX プロパティと ScaleY プロパティも定義しています。これにより、VisualElement を縦方向と横方向に別々にスケールできます。

または、XAML でデータ バインディングを指定することもできます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               Scale="{Binding Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

この例では、Binding マークアップ拡張機能にコンマで区切った SourcePath という 2 つのプロパティが設定されました。 Source プロパティは、埋め込み x:Reference マークアップ拡張に設定されています。それ以外の場合、BindingContext を設定するのと同じ構文になります。

Binding マークアップ拡張のコンテンツ プロパティは Path ですが、そのマークアップ拡張の Path= の部分は、式の中で最初のプロパティである場合にのみ省略できます。 Path= の部分を省略するには、2 つのプロパティを入れ替える必要があります。

Scale="{Binding Value, Source={x:Reference slider}}" />

XAML マークアップ拡張は、通常は中かっこで区切りますが、オブジェクト要素として表すこともできます。

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Source="{x:Reference slider}"
                 Path="Value" />
    </Label.Scale>
</Label>

この例では、Source プロパティと Path プロパティは標準の XAML 属性です。 値は引用符で囲んで使用し、属性はコンマで区切りません。 x:Reference マークアップ拡張は、オブジェクト要素にすることもできます。

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

この構文は一般的ではありませんが、複合オブジェクトを使用する場合に必要になることがあります。

これまでに示した例では、BindingBindingContext プロパティと Source プロパティを x:Reference マークアップ拡張に設定して、ページ上の別のビューを参照しています。 これら 2 つのプロパティは、Object 型であり、ソースのバインドに適したプロパティを含む任意のオブジェクトに設定することができます。 また、BindingContextSource プロパティを x:Static マークアップ拡張機能に設定して、静的プロパティまたはフィールドの値を参照したり、StaticResource マークアップ拡張機能に設定して、リソース ディクショナリに格納されているオブジェクトを参照したり、ビューモデルのインスタンスであることが多いオブジェクトを直接参照したりすることもできます。

Note

BindingSource プロパティと Path プロパティによってバインディング コンテキストが定義されるように BindingContext プロパティを Binding オブジェクトに設定することもできます。

バインディング コンテキストの継承

ソース オブジェクトは、Binding オブジェクトの BindingContext プロパティまたは Source プロパティを使用して指定できます。 両方が設定されている場合、BindingSource プロパティが BindingContext よりも優先されます。

重要

BindingContext プロパティの値はビジュアル ツリーを介して継承されます。

次の XAML の例は、バインディング コンテキストの継承を示します。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">
        <StackLayout VerticalOptions="Fill"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="End"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="Start"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />
    </StackLayout>
</ContentPage>

この例では、StackLayoutBindingContext プロパティが slider オブジェクトに設定されています。 このバインディング コンテキストは、LabelBoxView の両方によって継承され、これらは両方とも、Rotation プロパティが SliderValue に設定されています。

バインディング コンテキストの継承