次の方法で共有


第 16 章の概要: データ バインディング

Note

この本は 2016 年春に発行されて以降、改訂されていません。 多くの情報はまだ価値がありますが、一部の資料は古くなっており、トピックの中にはまったく正しくないものまたは不完全なものもあります。

プログラマーは、あるオブジェクトのプロパティが変更されたことを検出するイベント ハンドラーを作成し、それを使って別のオブジェクトのプロパティの値を変更することがよくあります。 このプロセスは、"データ バインディング" の手法を使用して自動化できます。 データ バインディングは、通常、XAML で定義され、ユーザー インターフェイスの定義の一部になります。

非常に多くの場合、このようなデータ バインディングによって、ユーザー インターフェイス オブジェクトが基になるデータに接続されます。 これは、次でさらに詳しく調べる手法です: 第18章: MVVM。 ただし、データ バインディングでは、2 つ以上のユーザー インターフェイス要素を接続することもできます。 この章に記載されているデータ バインディングの初期の例のほとんどは、この手法を示しています。

バインディングの基礎

データ バインディングでは、いくつかのプロパティ、メソッド、およびクラスが使用されます。

次の 2 つのクラスでは、バインディング用の XAML マークアップ拡張機能がサポートされています。

  • BindingExtension では Binding マークアップ拡張機能がサポートされています
  • ReferenceExtension では x:Reference マークアップ拡張機能がサポートされています

データ バインディングでは、次の 2 つのインターフェイスが使用されます。

  • System.ComponentModel 名前空間の INotifyPropertyChanged を使って、プロパティが変更されたときの通知が実装されます
  • IValueConverter は、データ バインディングにおいて値をある型から別の型に変換する、小規模のクラスを定義するために使用されます

データ バインディングによって、同じオブジェクトの 2 つのプロパティ、または (より一般的には) 2 つの異なるオブジェクトの 2 つのプロパティが接続されます。 これらの 2 つのプロパティは、"ソース" と "ターゲット" と呼ばれます。 一般に、ソース プロパティの変更によってターゲット プロパティの変更が発生しますが、この方向は逆になることがあります。 いずれにしても:

  • "ターゲット" プロパティは BindableProperty によってサポートされている必要があります
  • "ソース" プロパティは、通常、INotifyPropertyChanged を実装するクラスのメンバーです

INotifyPropertyChanged を実装するクラスでは、プロパティの値が変更されると PropertyChanged イベントが発生します。 BindableObject では INotifyPropertyChanged が実装されているため、BindableProperty によってサポートされているプロパティの値が変更されると PropertyChanged イベントが自動的に発生します。ただし、INotifyPropertyChanged を実装する独自のクラスを、BindableObject から派生することなく作成することもできます。

コードと XAML

OpacityBindingCode サンプルでは、コードでデータ バインディングを設定する方法が示されています。

  • ソースは、SliderValue プロパティです
  • ターゲットは、LabelOpacity プロパティです

2 つのオブジェクトは、Label オブジェクトの BindingContextSlider オブジェクトに設定することによって接続されます。 2 つのプロパティは、バインド可能なプロパティ OpacityProperty と、文字列として表される SliderValue プロパティを参照する、LabelSetBinding 拡張メソッドを呼び出すことによって接続されます。

Slider を操作すると、Label の表示がフェード イン、フェード アウトされます。

OpacityBindingXaml は、XAML でデータ バインディングが設定された同じプログラムです。 LabelBindingContext は、Slider を参照する x:Reference マークアップ拡張に設定され、LabelOpacity プロパティは、SliderValue プロパティを参照するその Path プロパティを使用して、Binding マークアップ拡張に設定されます。

ソースと BindingContext

BindingSourceCode サンプルでは、コードにおける別のアプローチが示されています。 Binding オブジェクトは、Source プロパティを Slider オブジェクトに設定し、Path プロパティを "Value" に設定することで作成されます。 次に、Label オブジェクトで BindableObjectSetBinding メソッドが呼び出されます。

Binding コンストラクターを使用して Binding オブジェクトを定義することもできます。

BindingSourceXaml サンプルには、XAML での同等の手法が示されています。 LabelOpacity プロパティは Binding マークアップ拡張に設定され、PathValue プロパティに、Source は埋め込みの x:Reference マークアップ拡張に設定されます。

要約すると、バインディング ソース オブジェクトを参照するには、次の 2 つの方法があります。

  • ターゲットの BindingContext プロパティを使用する
  • Binding オブジェクト自体の Source プロパティを使用する

両方を指定した場合は、2 番目が優先されます。 BindingContext の利点は、それがビジュアル ツリーを通じて伝達されることです。 これは、複数のターゲット プロパティが同じソース オブジェクトにバインドされている場合に、"非常に" 便利です。

WebViewDemo プログラムでは、WebView 要素を使ってこの手法が示されています。 前後に移動するための 2 つの Button 要素は、WebView を参照するその親から BindingContext を継承します。 次に、2 つのボタンの IsEnabled プロパティでは、WebView の読み取り専用プロパティ CanGoBack および CanGoForward の設定に基づいて、ボタンの IsEnabled プロパティをターゲットとする Binding マークアップ拡張が設定されています。

バインディング モード

BindingMode プロパティを、次の BindingMode 列挙型のメンバーに設定します。

  • OneWay: ソース プロパティに対する変更がターゲットに影響を与えるようにします
  • OneWayToSource: ターゲット プロパティに対する変更がソースに影響を与えるようにします
  • TwoWay: ソースとターゲットに対する変更が相互に影響を与えるようにします
  • Default: ターゲットの BindableProperty が作成されたときに指定された DefaultBindingMode を使用します。 何も指定されていなかった場合、既定値は、通常のバインド可能なプロパティの場合は OneWay、読み取り専用のバインド可能なプロパティの場合は OneWayToSource になります。

Note

BindingMode 列挙型には、ソース プロパティが変更されたときではなく、バインディング コンテキストが変更されたときにのみバインディングを適用するための OnTime も含まれるようになりました。

MVVM シナリオにおいてデータ バインディングのターゲットとなる可能性のあるプロパティには、通常、TwoWayDefaultBindingMode が設定されています。 次のとおりです。

  • SliderStepperValue プロパティ
  • SwitchIsToggled プロパティ
  • EntryEditorSearchBarText プロパティ
  • DatePickerDate プロパティ
  • TimePickerTime プロパティ

BindingModes サンプルでは、ターゲットが LabelFontSize プロパティであり、ソースが SliderValue プロパティであるデータ バインディングを使用した、4 つのバインディング モードが示されています。 これにより、各 Slider で対応する Label のフォント サイズを制御できるようになります。 ただし、Slider 要素は初期化されません。FontSize プロパティの DefaultBindingModeOneWay であるためです。

ReverseBinding サンプルでは、各 LabelFontSize プロパティを参照する、SliderValue プロパティのバインディングが設定されています。 これは後退しているように見えますが、SliderValue プロパティの DefaultBindingModeTwoWay であるため、Slider 要素をより適切に初期化することができます。

リバース バインディングのトリプル スクリーンショット

これは、MVVM でバインディングが定義される方法に似ています。この種類のバインディングは頻繁に使用します。

文字列の書式設定

ターゲット プロパティの型が string の場合、BindingBase によって定義されている StringFormat プロパティを使用して、ソースを string に変換できます。 オブジェクトを表示する静的な String.Format 書式設定を使用して、StringFormat プロパティを、使用する .NET 書式設定文字列に設定します。 マークアップ拡張内でこの書式設定文字列を使用する場合は、中かっこが埋め込みマークアップ拡張と間違えられないように、これを単一引用符で囲んでください。

ShowViewValues サンプルでは、XAML で StringFormat を使用する方法が示されています。

WhatSizeBindings サンプルでは、ContentPageWidth および Height プロパティへのバインディングを使用して、ページのサイズを表示する方法が示されています。

"Path" と呼ばれる理由

BindingPath プロパティがこのように呼ばれるのは、ピリオドで区切られた一連のプロパティとインデクサーを指定できるためです。 BindingPathDemos サンプルでは、いくつかの例が示されています。

バインディングの値コンバーター

バインディングのソース プロパティとターゲット プロパティが異なる型である場合は、バインディング コンバーターを使用して型の間で変換を行うことができます。 これは、IValueConverter インターフェイスを実装したクラスであり、2 つのメソッドが含まれています。ソースをターゲットに変換するための Convert と、ターゲットをソースに変換するための ConvertBack です。

Xamarin.FormsBook.Toolkit ライブラリの IntToBoolConverter クラスは、intbool に変換する 1 つの例です。 これは ButtonEnabler サンプルで示されています。そこでは、少なくとも 1 つの文字が Entry に入力された場合にのみ、Button が有効になります。

BoolToStringConverter クラスでは、boolstring に変換され、falsetrue の値に対して返されるテキストを指定するために、2 つのプロパティが定義されています。 BoolToColorConverter も似ています。 SwitchText サンプルでは、これら 2 つのコンバーターを使用して、Switch 設定に基づいてさまざまなテキストをさまざまな色で表示する方法が示されています。

ジェネリックの BoolToObjectConverter では、BoolToStringConverterBoolToColorConverter を置き換えることができます。これは、汎用的な、bool からオブジェクトへの任意の型のコンバーターとして機能します。

バインディングとカスタム ビュー

データ バインディングを使用してカスタム コントロールを簡略化できます。 NewCheckBox.cs コード ファイルでは、TextTextColorFontSizeFontAttributes、および IsChecked プロパティが定義されていますが、コントロールのビジュアル用のロジックはまったく含まれていません。 代わりに、NewCheckBox.cs.xaml ファイルには、分離コード ファイル内で定義されているプロパティに基づき、Label 要素のデータ バインディングを使用して、コントロールのビジュアルに対するすべてのマークアップが含まれています。

NewCheckBoxDemo サンプルでは、NewCheckBox カスタム コントロールが示されています。