XAML 読み込みと依存関係プロパティ

WPF での XAML プロセッサの現在の実装では、本質的に依存関係プロパティが認識されます。 WPF の XAML プロセッサでは、バイナリ XAML を読み込み、依存関係プロパティである属性を処理するときに、依存関係プロパティに対するプロパティ システム メソッドが使用されます。 これにより、プロパティ ラッパーは実質的にバイパスされます。 カスタム依存関係プロパティを実装するときは、この動作について考慮する必要があります。また、プロパティ ラッパーには、プロパティ システム メソッド GetValue および SetValue 以外の他のコードを配置しないようにする必要があります。

必須コンポーネント

このトピックは、利用者と作成者の両方として依存関係プロパティを理解しており、「依存関係プロパティの概要」と「カスタム依存関係プロパティ」を読んでいることを前提としています。 また、「WPF の XAML」と「XAML 構文の詳細」も読んでおく必要があります。

WPF XAML ローダーの実装とパフォーマンス

実装上の理由から、プロパティ ラッパーとそのセッターを使用するのではなく、プロパティを依存関係プロパティとして識別し、プロパティ システムの SetValue メソッドを使用してプロパティを設定する方が、計算がより低コストになります。 これは、XAML のプロセッサでは、マークアップとさまざまな文字列の構造によって示される型とメンバーの関係に関する知識だけに基づいて、バッキング コードのオブジェクト モデル全体を推測する必要があるためです。

型は xmlns 属性と assembly 属性の組み合わせによって参照されますが、メンバーを識別し、属性として設定できるサポートを判断し、プロパティ値でサポートされる型を解決するには、PropertyInfo を使用する広範なリフレクションが必要です。 特定の型に対する依存関係プロパティには、プロパティ システムを通じてストレージ テーブルとしてアクセスできるため、WPF によるその XAML プロセッサの実装では、このテーブルが使用され、依存関係プロパティ識別子 ABCProperty を使用して、包含する DependencyObject 派生型で SetValue を呼び出すことにより、特定のプロパティ ABC をより効率的に設定できることが推測されます。

カスタム依存関係プロパティに対する影響

現在の WPF によるプロパティ設定に対する XAML プロセッサ動作の実装では、ラッパーが完全にバイパスされるため、カスタム依存関係プロパティのラッパーの set 定義に追加のロジックを含めないでください。 そのようなロジックを set 定義に含めた場合、プロパティがコードではなく XAML で設定されていると、ロジックは実行されません。

同様に、XAML 処理からプロパティ値を取得する XAML プロセッサのその他の側面でも、ラッパーを使用するのではなく、GetValue が使用されます。 したがって、get 定義でも、GetValue の呼び出し以外のものを追加して実装しないようにする必要があります。

次の例は、ラッパーでの依存関係プロパティの推奨される定義です。ここでは、プロパティ識別子は publicstaticreadonly フィールドとして格納されており、getset の定義には、依存関係プロパティのバッキングを定義する必要なプロパティ システム メソッド以外のコードは含まれていません。


public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
  "AquariumGraphic",
  typeof(Uri),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(null,
      FrameworkPropertyMetadataOptions.AffectsRender,
      new PropertyChangedCallback(OnUriChanged)
  )
);
public Uri AquariumGraphic
{
  get { return (Uri)GetValue(AquariumGraphicProperty); }
  set { SetValue(AquariumGraphicProperty, value); }
}

Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty = DependencyProperty.Register("AquariumGraphic", GetType(Uri), GetType(AquariumObject), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf OnUriChanged)))
Public Property AquariumGraphic() As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set(ByVal value As Uri)
        SetValue(AquariumGraphicProperty, value)
    End Set
End Property

関連項目