次の方法で共有


読み取り専用の依存関係プロパティ (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 アクセス修飾子を使用できます。 依存関係プロパティの値が相互に影響するシナリオでは、対になった PropertyChangedCallbackCoerceValueCallback のコールバックを使用して値の変更をトリガーできます。 詳細については、「依存関係プロパティのメタデータ」を参照してください。

読み取り専用の依存関係プロパティの値を、登録するクラスの外部から変更する必要がある場合は、DependencyPropertyKeyinternal アクセス修飾子を使用できます。 たとえば、同じアセンブリ内のイベント ハンドラーから 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 への参照を持つものに書き込みアクセスを制限する場合は、読み取り専用の依存関係プロパティを使用します。

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

関連項目