第 11 章の概要: バインド可能なインフラストラクチャ
注意
この本は 2016 年春に発行されて以降、改訂されていません。 多くの情報はまだ価値がありますが、一部の資料は古くなっており、トピックの中にはまったく正しくないものまたは不完全なものもあります。
すべての C# プログラマは、C# の "プロパティ" について理解しています。 プロパティには、set アクセサーと get アクセサーのどちらか一方または両方が含まれます。 それらは、共通言語ランタイムの "CLR プロパティ" と呼ばれることがよくあります。
Xamarin.Forms では、BindableProperty
クラスによってカプセル化され、BindableObject
クラスによってサポートされる、"バインド可能プロパティ" と呼ばれる拡張プロパティ定義が定義されています。 これらのクラスは関連してはいますが、非常に異なります。BindableProperty
は、プロパティ自体を定義するために使用されます。BindableObject
は、バインド可能プロパティを定義するクラスの基底クラスであるという点で object
に似ています。
Xamarin.Forms のクラス階層
ClassHierarchy サンプルでは、リフレクションを使用して Xamarin.Forms のクラス階層が表示され、この階層において BindableObject
によって果たされる重要な役割が示されています。 BindableObject
は、Object
から派生し、それを親クラスとする Element
から、VisualElement
が派生します。 さらにこれを親として Page
と View
が派生し、それは Layout
に対する親クラスです。
BindableObject と BindableProperty の詳細
BindableObject
から派生したクラスでは、多くの CLR プロパティがバインド可能プロパティ "によってサポートされている" と言われます。 たとえば、Label
クラスの Text
プロパティは CLR プロパティですが、Label
クラスでは、 型の BindableProperty
TextProperty
という名前のパブリックな静的読み取り専用フィールドも定義されています。
アプリケーションは、 の プロパティLabel
をText
通常どおりに設定または取得できます。または、 で定義されたメソッドを引数でLabel.TextProperty
呼び出すことで、アプリケーションで BindableObject
をSetValue
設定Text
できます。 同様に、アプリケーションは、 メソッドを呼び出してプロパティの Text
値を GetValue
取得できます。もう一度引数を指定 Label.TextProperty
します。 これについては、PropertySettings サンプルを参照してください。
実際には、Text
CLR プロパティは、BindableObject
と Label.TextProperty
静的プロパティの組み合わせによって定義された SetValue
メソッドと GetValue
メソッドを使用して、完全に実装されます。
BindableObject
と BindableProperty
では、以下に対するサポートが提供されます。
- プロパティの既定値の指定
- 現在の値の格納
- プロパティ値を検証するためのメカニズムの提供
- 1 つのクラスの関連するプロパティ間の整合性の維持
- プロパティの変更への応答
- プロパティが変更されようとしているとき、または変更されたときの通知のトリガー
- データ バインディングのサポート
- スタイルのサポート
- 動的リソースのサポート
バインド可能プロパティによってサポートされるプロパティが変更されるたびに、BindableObject
によって、変更されたプロパティを示す PropertyChanged
イベントが生成されます。 プロパティが同じ値に設定されたときは、このイベントは生成されません。
一部のプロパティはバインド可能なプロパティによってサポートされず、 などのSpan
一部Xamarin.Formsのクラスは からBindableObject
派生しません。 BindableObject
で SetValue
メソッドと GetValue
メソッドが定義されているため、BindableObject
から派生したクラスのみがバインド可能プロパティをサポートできます。
Span
は からBindableObject
派生しないため、そのプロパティ (などText
) はバインド可能なプロパティによってサポートされません。 このため、Span
の Text
プロパティで DynamicResource
を設定すると、前の章の DynamicVsStatic サンプルで例外が発生します。 DynamicVsStaticCode サンプルでは、 でElement
定義された メソッドを使用して、コード内で動的リソースを設定するSetDynamicResource
方法を示します。 最初の引数は BindableProperty
型のオブジェクトです。
同様に、 で定義されるSetBinding
メソッドには、 型の最初の引数がありますBindableProperty
。BindableObject
バインド可能プロパティの定義
静的 BindableProperty.Create
メソッドを使用して、独自のバインド可能なプロパティを定義して、 型 BindableProperty
の静的読み取り専用フィールドを作成できます。
これは、Book.Toolkit ライブラリの AltLabel
クラスでXamarin.Forms示されています。 そのクラスは Label
から派生し、フォント サイズをポイント単位で指定できます。 PointSizedText サンプルを参照してください。
BindableProperty.Create
メソッドの 4 つの引数は必須です。
propertyName
: プロパティのテキスト名 (CLR プロパティ名と同じ)returnType
: CLR プロパティの型declaringType
: プロパティを宣言するクラスの型defaultValue
: プロパティの既定値
defaultValue
は object
型であるため、コンパイラは既定値の型を決定できる必要があります。 たとえば、returnType
が double
である場合、defaultValue
は単に 0 ではなく 0.0 のように設定する必要があります。そうしないと、型の不一致によって実行時に例外が発生します。
また、バインド可能プロパティに次のものが含まれるのもよくあることです。
propertyChanged
: プロパティの値が変更されたときに呼び出される静的メソッド。 最初の引数は、プロパティが変更されたクラスのインスタンスです。
BindableProperty.Create
に対する他の引数は、一般的ではありません。
defaultBindingMode
: データ バインディングとの関係で使用されます (「第 16 章「データ バインディング」を参照)。validateValue
: 有効な値を確認するためのコールバックpropertyChanging
: プロパティが変更されようとしていることを示すコールバックcoerceValue
: set 値を別の値に強制的に変換するためのコールバックdefaultValueCreate
: クラスのインスタンス間で共有できない既定値を作成するためのコールバック (たとえば、コレクション)
読み取り専用のバインド可能プロパティ
バインド可能プロパティは読み取り専用にできます。 読み取り専用のバインド可能なプロパティを作成するには、静的メソッド BindableProperty.CreateReadOnly
を呼び出して、 型 BindablePropertyKey
のプライベート静的読み取り専用フィールドを定義する必要があります。
次に、 オブジェクトを使用してオーバーロードを呼び出SetValue
すように CLR プロパティ set
の accesor private
をBindablePropertyKey
定義します。 これにより、プロパティがクラスの外部で設定されるのを防ぐことができます。
これは、BaskervillesCount サンプルで使用されるクラスで示されていますCountedLabel
。