次の方法で共有


読み取り専用の依存関係プロパティ (WPF .NET)

読み取り専用の依存関係プロパティを使用して、プロパティ値がコードの外部から設定されないようにすることができます。 この記事では、既存の読み取り専用の依存関係プロパティと、カスタムの読み取り専用依存関係プロパティを作成するためのシナリオと手法について説明します。

前提 条件

この記事では、依存関係プロパティの基本的な知識と、依存関係プロパティの概要読んだことを前提としています。 この記事の例に従うには、拡張アプリケーション マークアップ言語 (XAML) に慣れている場合や、WPF アプリケーションを記述する方法を理解している場合に役立ちます。

既存の読み取り専用の依存関係プロパティ

通常、読み取り専用の依存関係プロパティは状態を報告します。public アクセサーを使用して変更することはできません。 たとえば、Windows Presentation Foundation (WPF) フレームワークでは、IsMouseOver プロパティの値はマウス入力によってのみ決定されるため、読み取り専用として実装されます。 IsMouseOverが他の入力を許可した場合、マウス入力と一致しなくなる可能性があります。 public アクセサーでは設定できませんが、既存の読み取り専用の依存関係プロパティの多くは、複数の入力によって決定される値を持ちます。

読み取り専用の依存関係プロパティの使用

依存関係プロパティが通常ソリューションを提供するいくつかのシナリオでは、読み取り専用の依存関係プロパティは適用されません。 適用できないシナリオには、データ バインディング、値へのスタイルの適用、検証、アニメーション、継承などがあります。 ただし、読み取り専用の依存関係プロパティは、スタイルのプロパティ トリガーとして使用できます。 たとえば、IsMouseOver は、マウスがコントロールの上にあるときに、コントロールの背景、前景、またはその他の表示プロパティに対する変更をトリガーするために一般的に使用されます。 WPF プロパティ システムは、読み取り専用の依存関係プロパティの変更を検出して報告するため、プロパティ トリガー機能をサポートします。 読み取り専用の依存関係プロパティは、コレクション オブジェクト自体ではなく、コレクション要素のみを書き込み可能にする必要があるコレクション型の依存関係プロパティを実装する場合にも便利です。 詳細については、「コレクション型の依存関係プロパティ を参照してください。

手記

スタイルのプロパティ トリガーとして使用できるのは、通常の共通言語ランタイム プロパティではなく、依存関係プロパティのみです。

カスタム読み取り専用依存関係プロパティの作成

読み取り専用の依存関係プロパティを作成する前に、該当しないシナリオ 確認してください。

読み取り専用の依存関係プロパティを作成するプロセスは、読み取り/書き込み依存関係プロパティの作成と似ていますが、次のような違いがあります。

  • 読み取り専用プロパティを登録するときは、Registerの代わりに RegisterReadOnly を呼び出します。

  • CLR プロパティ ラッパーを実装するときは、パブリック set アクセサーがないことを確認します。

  • RegisterReadOnlyDependencyPropertyの代わりに DependencyPropertyKey を返します。 DependencyPropertyKey を非パブリック クラス メンバーに格納します。

選択したロジックを使用して、読み取り専用の依存関係プロパティの値を決定できます。 プロパティ値を初期またはランタイム ロジックの一部として設定するには、DependencyPropertyKey型のパラメーターを受け取る SetValue のオーバーロードを使用することをお勧めします。 プロパティ システムを回避し、バッキング フィールドを直接設定するには、SetValue を使用することをお勧めします。

アプリケーション内で読み取り専用の依存関係プロパティの値を設定する方法と場所は、DependencyPropertyKeyを格納するクラス メンバーに割り当てるアクセス レベルに影響します。 依存関係プロパティを登録するクラス内からのみプロパティ値を設定する場合は、private アクセス修飾子を使用できます。 依存関係プロパティの値が相互に影響するシナリオでは、ペアの PropertyChangedCallback コールバックと CoerceValueCallback コールバックを使用して値の変更をトリガーできます。 詳細については、「依存関係プロパティのメタデータ 」を参照してください。

読み取り専用の依存関係プロパティの値を登録するクラスの外部から変更する必要がある場合は、DependencyPropertyKeyinternal アクセス修飾子を使用できます。 たとえば、同じアセンブリ内のイベント ハンドラーから SetValue を呼び出す場合があります。 次の例では、RegisterReadOnly を呼び出して FishCount読み取り専用の依存関係プロパティを作成する Aquarium クラスを定義します。 DependencyPropertyKey は、同じアセンブリ内のコードが読み取り専用の依存関係プロパティ値を変更できるように、internal static readonly フィールドに割り当てられます。

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への参照を持つユーザーに書き込みアクセスを制限する場合は、読み取り専用の依存関係プロパティを使用します。

これに対し、読み取り/書き込み依存関係プロパティの依存関係プロパティ識別子には、割り当てるアクセス修飾子に関係なく、プロパティ システムからアクセスできます。 詳細については、依存関係プロパティのセキュリティを参照してください。

関連項目