XAML 読み込みと依存関係プロパティXAML Loading and Dependency Properties

XAMLXAML プロセッサの現在の WPFWPF 実装は、本質的に依存関係プロパティを認識しています。The current WPFWPF implementation of its XAMLXAML processor is inherently dependency property aware. WPFWPF XAMLXAML プロセッサは、バイナリ XAMLXAML を読み込み、依存関係プロパティである属性を処理するときに、依存関係プロパティのプロパティシステムメソッドを使用します。The WPFWPF XAMLXAML processor uses property system methods for dependency properties when loading binary XAMLXAML and processing attributes that are dependency properties. これにより、プロパティラッパーが効果的にバイパスされます。This effectively bypasses the property wrappers. カスタム依存関係プロパティを実装する場合は、この動作について考慮する必要があります。また、プロパティシステムメソッド GetValue および SetValue以外の他のコードをプロパティラッパーに配置しないようにする必要があります。When you implement custom dependency properties, you must account for this behavior and should avoid placing any other code in your property wrapper other than the property system methods GetValue and SetValue.

必要条件Prerequisites

このトピックでは、コンシューマーと作成者の両方の依存関係プロパティと、依存関係プロパティの概要カスタム依存関係プロパティを理解していることを前提としています。This topic assumes that you understand dependency properties both as consumer and author and have read Dependency Properties Overview and Custom Dependency Properties. また、「Xaml の概要 (WPF)」および「 Xaml 構文の詳細」も参照してください。You should also have read XAML Overview (WPF) and XAML Syntax In Detail.

WPF XAML ローダーの実装とパフォーマンスThe WPF XAML Loader Implementation, and Performance

実装上の理由から、プロパティを依存関係プロパティとして識別し、プロパティラッパーとその setter を使用するのではなく、プロパティを設定するためにプロパティシステム SetValue メソッドにアクセスすると、計算コストが低くなります。For implementation reasons, it is computationally less expensive to identify a property as a dependency property and access the property system SetValue method to set it, rather than using the property wrapper and its setter. これは、XAMLXAML のプロセッサは、マークアップとさまざまな文字列の構造によって示される型およびメンバーのリレーションシップを知っているだけで、バッキングコードのオブジェクトモデル全体を推論する必要があるためです。This is because a XAMLXAML processor must infer the entire object model of the backing code based only on knowing the type and member relationships that are indicated by the structure of the markup and various strings.

型は xmlns 属性とアセンブリ属性の組み合わせによって参照されますが、メンバーを識別し、属性としての設定がサポートされているかどうかを判断し、プロパティ値でサポートされる型を解決するために広範なリフレクションが必要になります。PropertyInfoを使用します。The type is looked up through a combination of xmlns and assembly attributes, but identifying the members, determining which could support being set as an attribute, and resolving what types the property values support would otherwise require extensive reflection using PropertyInfo. 特定の型の依存関係プロパティは、プロパティシステムを使用してストレージテーブルとしてアクセスできるため、その XAMLXAML プロセッサの WPFWPF 実装では、このテーブルを使用して、特定のプロパティABCがによってより効率的に設定されることを推論します。依存関係プロパティ識別子ABCPropertyを使用して、それを含む DependencyObject 派生型に対して SetValue を呼び出します。Because dependency properties on a given type are accessible as a storage table through the property system, the WPFWPF implementation of its XAMLXAML processor uses this table and infers that any given property ABC can be more efficiently set by calling SetValue on the containing DependencyObject derived type, using the dependency property identifier ABCProperty.

カスタム依存関係プロパティの影響Implications for Custom Dependency Properties

プロパティ設定の XAMLXAML プロセッサ動作の現在の WPFWPF 実装では、ラッパーが完全にバイパスされるため、カスタム依存関係プロパティのラッパーのセット定義に追加のロジックを含めないでください。Because the current WPFWPF implementation of the XAMLXAML processor behavior for property setting bypasses the wrappers entirely, you should not put any additional logic into the set definitions of the wrapper for your custom dependency property. このようなロジックをセット定義に含めた場合、プロパティがコードではなく XAMLXAML で設定されていると、ロジックは実行されません。If you put such logic in the set definition, then the logic will not be executed when the property is set in XAMLXAML rather than in code.

同様に、XAMLXAML 処理からプロパティ値を取得する XAMLXAML プロセッサのその他の側面は、ラッパーを使用するのではなく、GetValue も使用します。Similarly, other aspects of the XAMLXAML processor that obtain property values from XAMLXAML processing also use GetValue rather than using the wrapper. したがって、GetValue 呼び出しを超える get 定義では、追加の実装も回避する必要があります。Therefore, you should also avoid any additional implementation in the get definition beyond the GetValue call.

次の例は、ラッパーを含む推奨される依存関係プロパティの定義です。ここで、プロパティ識別子は readonly フィールド static public として格納され、get 定義と set 定義には、必要なプロパティを超えるコードは含まれていません。依存関係プロパティのバッキングを定義するシステムメソッド。The following example is a recommended dependency property definition with wrappers, where the property identifier is stored as a public static readonly field, and the get and set definitions contain no code beyond the necessary property system methods that define the dependency property backing.


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

関連項目See also