XAML 読み込みと依存関係プロパティ
更新 : 2007 年 11 月
現在の WPF 実装の XAML プロセッサは、依存関係プロパティに最初から対応しています。WPFXAML プロセッサは、バイナリ XAML を読み込むとき、および依存関係プロパティである属性を処理するときに、依存関係プロパティ用のプロパティ システム メソッドを使用します。この結果、プロパティ ラッパーは実質的に省略されます。カスタムの依存関係プロパティを実装するときには、この動作を考慮に入れて、プロパティ システム メソッド GetValue および SetValue 以外のコードをプロパティ ラッパーに記述することは避ける必要があります。
このトピックには次のセクションが含まれています。
- 必要条件
- WPF XAML ローダーの実装とパフォーマンス
- カスタム依存関係プロパティでの影響
- 関連トピック
必要条件
このトピックは、依存関係プロパティを使用と作成の両面から理解していることと、「依存関係プロパティの概要」および「カスタム依存関係プロパティ」を通読していることを前提としています。また、「XAML の概要」および「XAML 構文用語」も通読している必要があります。
WPF XAML ローダーの実装とパフォーマンス
実装上の理由から、プロパティを依存関係プロパティとして指定して、プロパティ システムの SetValue メソッドを使用して設定する方が、プロパティ ラッパーおよびその setter を使用するよりも、処理の負荷が抑えられます。その理由は、XAML プロセッサは、マークアップとさまざまな文字列の構造で示された、型とメンバの関係を把握し、それだけを頼りに、基になるコードのオブジェクト モデル全体を推論する必要があるためです。
型は xmlns とアセンブリ属性の組み合わせで検索されますが、メンバの識別、属性として設定された値をどれがサポートするかの判断、およびプロパティ値がどの型をサポートするかの解決は、PropertyInfo によるリフレクションを多用することになります。任意の型の依存関係プロパティは、プロパティ システムを通じてストレージ テーブルとしてアクセスできます。このため、WPF 実装の XAML プロセッサは、このテーブルを使用します。そして、プロパティ ABC を設定するには、依存関係プロパティ識別子 ABCProperty を使用して、所属する DependencyObject 派生型の SetValue を呼び出す方が効率がよいと推論します。
カスタム依存関係プロパティでの影響
現在の WPF 実装の XAML プロセッサでは、プロパティ設定の動作でラッパーが完全に省略されるため、カスタム依存関係プロパティのラッパーの set の定義には、追加的なロジックを記述しないことが必要です。追加的なロジックを set の定義に記述した場合、プロパティがコードではなく XAML で設定されたときには、ロジックは実行されません。
同様に、XAML プロセッサが XAML 処理からプロパティ値を取得するときにも、ラッパーではなく GetValue が使用されます。したがって、get の定義では、GetValue の呼び出し以外に追加的な処理を実装することは避ける必要があります。
次の例は、依存関係プロパティで推奨される定義方法です。ラッパーを使用して、プロパティ識別子は public static readonly フィールドとして格納し、get と set の定義には、依存関係プロパティのバッキングを定義するために必要なプロパティ システム メソッド以外のコードは含まれていません。
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); }
}