読み取り専用の依存関係プロパティRead-Only Dependency Properties

このトピックでは、既存の読み取り専用の依存関係プロパティ、カスタムの読み取り専用の依存関係プロパティを作成するシナリオと手法など、読み取り専用の依存関係プロパティについて説明します。This topic describes read-only dependency properties, including existing read-only dependency properties and the scenarios and techniques for creating a custom read-only dependency property.


このトピックでは、依存関係プロパティの実装の基本シナリオとカスタム依存関係プロパティへのメタデータの適用方法を理解していることを前提とします。This topic assumes that you understand the basic scenarios of implementing a dependency property, and how metadata is applied to a custom dependency property. 詳細については、「カスタム依存関係プロパティ」および「依存関係プロパティのメタデータ」を参照してください。See Custom Dependency Properties and Dependency Property Metadata for context.

既存の読み取り専用の依存関係プロパティExisting Read-Only Dependency Properties

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) フレームワークで定義されている依存関係プロパティの一部は読み取り専用です。Some of the dependency properties defined in the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) framework are read-only. 読み取り専用の依存関係プロパティを指定する一般的な理由は、それらが状態決定に使用されるプロパティであるにも関わらず、その状態は多くの要因の影響を受け、プロパティをその状態に設定するだけではユーザー インターフェイス設計の観点から望ましくないことにあります。The typical reason for specifying a read-only dependency property is that these are properties that should be used for state determination, but where that state is influenced by a multitude of factors, but just setting the property to that state isn't desirable from a user interface design perspective. たとえば、プロパティ IsMouseOver はマウス入力で決定される表示上の状態に過ぎません。For example, the property IsMouseOver is really just surfacing state as determined from the mouse input. 実際にマウス入力を行わずにプログラムでこの値を設定しようとすると、予期しない結果になり、不整合が生じる原因になります。Any attempt to set this value programmatically by circumventing the true mouse input would be unpredictable and would cause inconsistency.

設定可能ではないため、読み取り専用の依存関係プロパティは、依存関係プロパティがソリューションを通常提供するシナリオの多くには適切ではありません (データ バインディング、直接スタイル設定可能な値、検証、アニメーション、継承など)。By virtue of not being settable, read-only dependency properties aren't appropriate for many of the scenarios for which dependency properties normally offer a solution (namely: data binding, directly stylable to a value, validation, animation, inheritance). それでも、設定不可能な読み取り専用依存関係プロパティには、プロパティ システムの依存関係プロパティによってサポートされるいくつかの追加機能があります。Despite not being settable, read-only dependency properties still have some of the additional capabilities supported by dependency properties in the property system. その他の機能のうち最も重要なのは、読み取り専用の依存関係プロパティはスタイルのプロパティ トリガーとして使用できることです。The most important remaining capability is that the read-only dependency property can still be used as a property trigger in a style. 通常の共通言語ランタイム (CLR) プロパティではトリガーを有効にできません。依存関係プロパティであることが必要です。You can't enable triggers with a normal common language runtime (CLR) property; it needs to be a dependency property. 上記の IsMouseOver プロパティは、コントロールのスタイルを定義するのが便利なシナリオのよい例です。コントロール内の複合要素の背景や前景のような一部の表示関連のプロパティは、コントロールの定義済み領域をユーザーがマウスでポイントすると変化します。The aforementioned IsMouseOver property is a perfect example of a scenario where it might be quite useful to define a style for a control, where some visible property such as a background, foreground, or similar properties of composited elements within the control will change when the user places a mouse over some defined region of your control. 読み取り専用の依存関係プロパティの変化は、プロパティ システム固有の無効化プロセスによって検出して報告することもでき、これは実際にはプロパティ トリガー機能を内部的にサポートします。Changes in a read-only dependency property can also be detected and reported by the property system's inherent invalidation processes, and this in fact supports the property trigger functionality internally.

読み取り専用のカスタム依存関係プロパティの作成Creating Custom Read-Only Dependency Properties

多くの一般的な依存関係プロパティのシナリオで読み取り専用依存関係プロパティが機能しない理由に関する前のセクションを参照してください。Make sure to read the section above regarding why read-only dependency properties won't work for many typical dependency-property scenarios. ただし、適切なシナリオがある場合は、独自の読み取り専用依存関係プロパティを作成してもかまいません。But if you have an appropriate scenario, you may wish to create your own read-only dependency property.

読み取り専用の依存関係プロパティを作成するプロセスの大部分は、「カスタム依存関係プロパティ」と「依存関係プロパティの実装」のトピックの説明と同じです。Much of the process of creating a read-only dependency property is the same as is described in the Custom Dependency Properties and Implement a Dependency Property topics. ただし、次の 3 つの重要な違いがあります。There are three important differences:

  • プロパティを登録するときは、プロパティ登録用の通常の Register メソッドではなく、RegisterReadOnly メソッドを呼び出します。When registering your property, call the RegisterReadOnly method instead of the normal Register method for property registration.

  • CLR の "ラッパー" プロパティを実装するときは、公開するパブリック ラッパーの読み取り専用状態が矛盾しないよう、ラッパーにも set を実装しないようにする必要があります。When implementing the CLR "wrapper" property, make sure that the wrapper too doesn't have a set implementation, so that there is no inconsistency in read-only state for the public wrapper you expose.

  • 読み取り専用の登録によって返されるオブジェクトは、DependencyProperty ではなく DependencyPropertyKey です。The object returned by the read-only registration is DependencyPropertyKey rather than DependencyProperty. やはりこのフィールドをメンバーとして格納する必要がありますが、通常は、型のパブリック メンバーにはしません。You should still store this field as a member but typically you would not make it a public member of the type.

読み取り専用の依存関係プロパティを補足するために使用するプライベートのフィールドまたは値はすべて、適当なロジックを使用して完全に書き込み可能にしてかまいません。Whatever private field or value you have backing your read-only dependency property can of course be fully writable using whatever logic you decide. ただし、初期化で、またはランタイム ロジックの一部として、プロパティを設定する最も簡単な方法は、プロパティ システムを使用しないでプライベートなバッキング フィールドを直接設定するのではなく、プロパティ システムの API を使用する方法です。However, the most straightforward way to set the property either initially or as part of runtime logic is to use the property system's APIs, rather than circumventing the property system and setting the private backing field directly. 具体的には、DependencyPropertyKey 型のパラメーターを受け取る SetValue のシグネチャがあります。In particular, there is a signature of SetValue that accepts a parameter of type DependencyPropertyKey. アプリケーション ロジック内でプログラムによってこの値を設定する方法と場所により、依存関係プロパティを最初に登録したときに作成される DependencyPropertyKey に対するアクセスの設定方法が影響を受けます。How and where you set this value programmatically within your application logic will affect how you may wish to set access on the DependencyPropertyKey created when you first registered the dependency property. このロジックすべてをクラス内で処理する場合はプライベートにでき、アセンブリの他の部分から設定する必要がある場合は内部に設定します。If you handle this logic all within the class you could make it private, or if you require it to be set from other portions of the assembly you might set it internal. 1 つの方法は、格納されているプロパティ値の変更が必要であることをクラスのインスタンスに通知する関連イベントのクラス イベント ハンドラー内で、SetValue を呼び出すというものです。One approach is to call SetValue within a class event handler of a relevant event that informs a class instance that the stored property value needs to be changed. もう 1 つの方法は、登録のときにプロパティのメタデータの一部として、ペアになった PropertyChangedCallback コールバックと CoerceValueCallback コールバックを使用して、依存関係プロパティを結び付けるというものです。Another approach is to tie dependency properties together by using paired PropertyChangedCallback and CoerceValueCallback callbacks as part of those properties' metadata during registration.

DependencyPropertyKey はプライベートであり、コードの外部のプロパティ システムによっては伝達されないので、読み取り専用の依存関係プロパティの方が、読み取り/書き込み依存関係プロパティより設定のセキュリティが優れています。Because the DependencyPropertyKey is private, and is not propagated by the property system outside of your code, a read-only dependency property does have better setting security than a read-write dependency property. 読み取り/書き込み依存関係プロパティの場合は、識別するフィールドは明示的または暗黙的にパブリックであり、したがってプロパティは広範に設定可能です。For a read-write dependency property, the identifying field is explicitly or implicitly public and thus the property is widely settable. 詳細については、「依存関係プロパティのセキュリティ」を参照してください。For more specifics, see Dependency Property Security.

関連項目See also