添付プロパティ

添付プロパティを使用すると、オブジェクトがそれ自体のクラスでは定義されていないプロパティの値を割り当てることができます。 たとえば、子要素は添付プロパティを使用して、ユーザー インターフェイスでの表示方法を親要素に通知できます。 Grid コントロールを使用すると、Grid.Row 添付プロパティと Grid.Column 添付プロパティを設定することで、子の行と列を指定できます。 Grid.RowGrid.Column は添付プロパティです。これは、Grid 自体ではなく、Grid の子要素に設定されるためです。

バインド可能なプロパティは、次のシナリオで添付プロパティとして実装する必要があります。

  • 定義するクラス以外のクラスで使用できるプロパティ設定機構が必要である場合。
  • クラスが他のクラスと簡単に統合する必要があるサービスを表す場合。

バインド可能オブジェクトの詳細については、バインド可能プロパティに関する記事を参照してください。

添付プロパティを作成する

添付プロパティを作成するプロセスは次のとおりです。

  1. CreateAttached メソッド オーバーロードのいずれかを使用して BindableProperty インスタンスを作成します。
  2. 添付プロパティのアクセサーとして、static GetPropertyName および SetPropertyName メソッドを指定します。

プロパティを作成する

他の型で使用する添付プロパティを作成する場合、プロパティが作成されるクラスは BindableObject から派生する必要はありません。 ただし、アクセサーの ターゲット プロパティは、BindableObject から派生する必要があります。

添付プロパティは、BindableProperty 型の public static readonly プロパティを宣言すれば作成できます。 バインド可能なプロパティは、いずれかの BindableProperty.CreateAttached メソッド オーバーロードの戻り値に設定する必要があります。 宣言は、所有するクラスの本文内に含める必要がありますが、メンバー定義の外部にある必要があります。

重要

添付プロパティの名前付け規則は、添付プロパティ識別子が CreateAttached メソッドで指定されたプロパティ名と一致する必要があり、"プロパティ" が追加されていることです。

次の例は、コードに添付プロパティを設定する方法を示しています。

public static readonly BindableProperty HasShadowProperty =
  BindableProperty.CreateAttached ("HasShadow", typeof(bool), typeof(ShadowEffect), false);

これにより、bool 型の HasShadowProperty という名前の添付プロパティが作成されます。 このプロパティは ShadowEffect クラスが所有し、false の既定値があります。

バインド可能なプロパティ (作成時に指定できるパラメーターなど) の作成の詳細については、「バインド可能なプロパティの作成」をご覧ください。

アクセサーを作成する

静的 GetPropertyName メソッドと SetPropertyName メソッドは、添付プロパティのアクセサーとして必要です。それ以外の場合、プロパティ システムは添付プロパティを使用できません。 GetPropertyName アクセサーは、次のシグネチャに準拠している必要があります。

public static valueType GetPropertyName(BindableObject target)

GetPropertyName アクセサーは、添付プロパティの対応する BindableProperty フィールドに含まれている値を返す必要があります。 これを実現するには、GetValue メソッドを呼び出し、値を取得するバインド可能なプロパティ識別子を渡し、結果の値を必要な型にキャストします。

SetPropertyName アクセサーは、次のシグネチャに準拠している必要があります。

public static void SetPropertyName(BindableObject target, valueType value)

SetPropertyName アクセサーは、添付プロパティの対応する BindableProperty フィールドの値を設定する必要があります。 これを実現するには、SetValue メソッドを呼び出し、値を設定するバインド可能なプロパティ識別子と設定する値を渡します。

どちらのアクセサーでも、ターゲット オブジェクトは BindableObject の一部であるか、それから派生する必要があります。

次のコード例では、HasShadow 添付プロパティのアクセサーを示しています。

public static bool GetHasShadow (BindableObject view)
{
  return (bool)view.GetValue (HasShadowProperty);
}

public static void SetHasShadow (BindableObject view, bool value)
{
  view.SetValue (HasShadowProperty, value);
}

添付プロパティを使用する

添付プロパティが作成されると、XAML またはコードから使用できます。 XAML では、これは、共通言語ランタイム (CLR) 名前空間名と、必要に応じて、アセンブリ名を示す名前空間宣言を使用して、プレフィックスを持つ名前空間を宣言することによって実現されます。 詳細については、「XAML 名前空間」をご覧ください。

次のコード例は、カスタム型を参照しているアプリケーション コードと同じアセンブリ内に定義されている添付プロパティを含むカスタム型の XAML 名前空間を示しています。

<ContentPage ... xmlns:local="clr-namespace:EffectsDemo" ...>
  ...
</ContentPage>

次に、この名前空間宣言が、次の XAML コード例に示すように、特定のコントロールに添付プロパティを設定するときに使用されます。

<Label Text="Label Shadow Effect" local:ShadowEffect.HasShadow="true" />

これと同じ C# コードの例は次のとおりです。

var label = new Label { Text = "Label Shadow Effect" };
ShadowEffect.SetHasShadow (label, true);

スタイル付きの添付プロパティを使用する

添付プロパティは、スタイルによってコントロールに追加することもできます。 次の XAML コード例は、HasShadow 添付プロパティを使用する "明示的な" スタイルを示しています。これは、Label コントロールに適用できます。

<Style x:Key="ShadowEffectStyle" TargetType="Label">
  <Style.Setters>
    <Setter Property="local:ShadowEffect.HasShadow" Value="true" />
  </Style.Setters>
</Style>

Style は、次のコード例に示すように、StaticResource マークアップ拡張を使用して自身の Style プロパティを Style インスタンスに設定することで、Label に適用できます。

<Label Text="Label Shadow Effect" Style="{StaticResource ShadowEffectStyle}" />

スタイルの詳細については、 のスタイルに関するページを参照してください。

詳細シナリオ

添付プロパティの作成時に、添付プロパティの高度なシナリオを有効にするために設定できるオプション パラメーターがいくつかあります。 これには、プロパティの変更の検出、プロパティ値の検証、プロパティ値の強制化が含まれます。 詳細については、「詳細シナリオ」をご覧ください。