読み取り専用の依存関係プロパティ (WPF .NET)
読み取り専用の依存関係プロパティを使用して、プロパティ値がコードの外部から設定されないようにすることができます。 この記事では、既存の読み取り専用の依存関係プロパティと、読み取り専用のカスタム依存関係プロパティを作成するためのシナリオと手法について説明します。
前提条件
この記事では、依存関係プロパティの基本的な知識と、依存関係プロパティの概要に関する記事を参照済みであることを前提としています。 この記事の例について理解するには、Extensible Application Markup Language (XAML) を使い慣れていて、WPF アプリケーションの記述方法を理解していると役に立ちます。
既存の読み取り専用の依存関係プロパティ
通常、読み取り専用の依存関係プロパティは状態を報告します。public
アクセサーを使用して変更することはできません。 たとえば、Windows Presentation Foundation (WPF) フレームワークでは、IsMouseOver プロパティは読み取り専用として実装されます。その値はマウス入力によってのみ決定されるためです。 IsMouseOver
が他の入力を許可すると、その値がマウス入力と一致しなくなる可能性があります。 public
アクセサーを使用して設定することはできませんが、多くの既存の読み取り専用の依存関係プロパティには、複数の入力によって決定される値があります。
読み取り専用の依存関係プロパティの使用
依存関係プロパティが通常のソリューションを提供するいくつかのシナリオでは、読み取り専用の依存関係プロパティは適用されません。 適用できないシナリオには、データ バインディング、値へのスタイルの適用、検証、アニメーション、継承などがあります。 ただし、読み取り専用の依存関係プロパティは、スタイルのプロパティ トリガーとして使用できます。 たとえば、IsMouseOver は通常、マウスが上にあるときに、コントロールの背景、前景、またはその他の表示されるプロパティに対する変更をトリガーするために使用されます。 WPF プロパティ システムでは、読み取り専用の依存関係プロパティの変更を検出して報告し、プロパティ トリガー機能をサポートします。 読み取り専用の依存関係プロパティは、コレクション オブジェクト自体ではなく、コレクション要素のみを書き込み可能にする必要があるコレクション型の依存関係プロパティを実装する場合にも便利です。 詳細については、「コレクション型依存関係プロパティ」を参照してください。
注意
通常の共通言語ランタイム プロパティではなく、依存関係プロパティのみがスタイルのプロパティ トリガーとして使用できます。
読み取り専用のカスタム依存関係プロパティの作成
読み取り専用の依存関係プロパティを作成する前に、適用できないシナリオを確認してください。
読み取り専用の依存関係プロパティを作成するプロセスは、読み取り/書き込み依存関係プロパティの作成と多くの点で似ていますが、次のような違いがあります。
読み取り専用プロパティを登録する場合は、Register の代わりに RegisterReadOnly を呼び出します。
CLR プロパティ ラッパーを実装するときは、パブリック
set
アクセサーがないことを確認します。RegisterReadOnly
は、DependencyProperty の代わりに DependencyPropertyKey を返します。 非パブリック クラス メンバーにDependencyPropertyKey
を格納します。
選択した任意のロジックを使用して、読み取り専用の依存関係プロパティの値を決定できます。 プロパティ値を初期またはランタイム ロジックの一部として設定するには、DependencyPropertyKey
型のパラメーターを受け取る SetValue のオーバーロードを使用することをお勧めします。 SetValue
の使用は、プロパティ システムを回避したり、バッキング フィールドを直接設定したりするよりも適しています。
アプリケーション内で読み取り専用依存関係プロパティの値を設定する方法と場所は、DependencyPropertyKey
を格納するクラス メンバーに割り当てるアクセス レベルに影響します。 依存関係プロパティを登録するクラス内からのみプロパティ値を設定する場合は、private
アクセス修飾子を使用できます。 依存関係プロパティの値が相互に影響するシナリオでは、対になった PropertyChangedCallback と CoerceValueCallback のコールバックを使用して値の変更をトリガーできます。 詳細については、「依存関係プロパティのメタデータ」を参照してください。
読み取り専用の依存関係プロパティの値を、登録するクラスの外部から変更する必要がある場合は、DependencyPropertyKey
に internal
アクセス修飾子を使用できます。 たとえば、同じアセンブリ内のイベント ハンドラーから SetValue
を呼び出す場合があります。 次の例では、読み取り専用の依存関係プロパティ FishCount
を作成するために RegisterReadOnly
を呼び出す Aquarium クラスを定義します。 internal static readonly
フィールドに DependencyPropertyKey
が割り当てられているため、同じアセンブリ内のコードで読み取り専用の依存関係プロパティ値を変更できます。
public class Aquarium : DependencyObject
{
// Register a dependency property with the specified property name,
// property type, owner type, and property metadata.
// Assign DependencyPropertyKey to a nonpublic field.
internal static readonly DependencyPropertyKey FishCountPropertyKey =
DependencyProperty.RegisterReadOnly(
name: "FishCount",
propertyType: typeof(int),
ownerType: typeof(Aquarium),
typeMetadata: new FrameworkPropertyMetadata());
// Declare a public get accessor.
public int FishCount =>
(int)GetValue(FishCountPropertyKey.DependencyProperty);
}
Public Class Aquarium
Inherits DependencyObject
' Register a dependency property with the specified property name,
' property type, owner type, And property metadata.
' Assign DependencyPropertyKey to a nonpublic field.
Friend Shared ReadOnly FishCountPropertyKey As DependencyPropertyKey =
DependencyProperty.RegisterReadOnly(
name:="FishCount",
propertyType:=GetType(Integer),
ownerType:=GetType(Aquarium),
typeMetadata:=New FrameworkPropertyMetadata())
' Declare a public get accessor.
Public ReadOnly Property FishCount As Integer
Get
Return GetValue(FishCountPropertyKey.DependencyProperty)
End Get
End Property
End Class
WPF プロパティ システムでは、DependencyPropertyKey はコードの外部に伝達されないため、読み取り専用の依存関係プロパティの方が、読み取り/書き込み依存関係プロパティよりも書き込みセキュリティが優れています。 DependencyPropertyKey
への参照を持つものに書き込みアクセスを制限する場合は、読み取り専用の依存関係プロパティを使用します。
これに対し、読み取り/書き込み依存関係プロパティの依存関係プロパティ識別子は、割り当てるアクセス修飾子に関係なく、プロパティ システムからアクセスできます。 詳細については、「依存関係プロパティのセキュリティ」を参照してください。
関連項目
.NET Desktop feedback