Windows Presentation Foundation (WPF) は、プロパティの値の変更に応じて発生する複数のイベントを定義します。 多くの場合、このプロパティは依存関係プロパティです。 イベント自体は、イベントを要素ツリー経由でルーティングするか、プロパティが変更されたオブジェクトでのみ発生するかに応じて、ルーティング イベントまたは標準共通言語ランタイム (CLR) イベントにすることができます。 後者のシナリオは、プロパティの変更がプロパティ値が変更されたオブジェクトにのみ関連する場合に適用されます。
[前提条件]
この記事では、依存関係プロパティに関する基本的な知識と、 ルーティング イベントの概要を読んだことを前提としています。
プロパティ変更イベントの識別
プロパティの変更を報告するすべてのイベントが、シグネチャまたは名前付けパターンによってプロパティ変更イベントとして明示的に識別されるわけではありません。 SDK ドキュメントでは、イベントを持つプロパティを相互参照し、イベントがプロパティ値の変更に直接関連付けられているかどうかを示します。
一部のイベントでは、プロパティ変更イベントに固有のイベント データ型とデリゲートが使用されます。 たとえば、 RoutedPropertyChanged イベントと DependencyPropertyChanged イベントにはそれぞれ特定のシグネチャがあります。 これらのイベントの種類については、次のセクションで説明します。
RoutedPropertyChanged イベント
RoutedPropertyChanged イベントにはRoutedPropertyChangedEventArgs<T>イベント データとRoutedPropertyChangedEventHandler<T>デリゲートがあります。 イベント データとデリゲートの両方に、ジェネリック型パラメーター T
があります。 ハンドラーを定義するときに、変更されたプロパティの実際の型を指定します。 イベント データには、ランタイム型が変更されたプロパティと同じ OldValue プロパティと NewValue プロパティが含まれます。
名前の "ルーティング" 部分は、プロパティ変更イベントがルーティング イベントとして登録されていることを示します。 プロパティ変更 ルーティング イベントの利点は、子要素のプロパティが変更されるたびに親要素に通知される点です。 つまり、複合パーツの値が変更されると、コントロールの最上位要素はプロパティ変更イベントを受け取ります。 たとえば、RangeBaseなどのSlider コントロールを組み込んだコントロールを作成するとします。 スライダー パーツで Value プロパティが変更された場合は、パーツではなく親コントロールでその変更を処理できます。
プロパティ変更イベント ハンドラーを使用してプロパティ値を検証することは避けてください。これは、ほとんどのプロパティ変更イベントの設計上の意図ではないのでです。 一般に、プロパティ変更イベントは、コードの他のロジック領域の値の変更に応答できるように提供されます。 プロパティ変更イベント ハンドラー内からプロパティ値を再度変更することはお勧めしません。ハンドラーの実装によっては、意図しない再帰が発生する可能性があります。
プロパティがカスタム依存関係プロパティである場合、またはインスタンス化コードを定義した派生クラスを使用している場合、WPF プロパティ システムは、プロパティの変更を追跡する優れた方法を備えます。 その方法は、組み込みの CoerceValueCallback と PropertyChangedCallback プロパティ システムのコールバックを使用することです。 WPF プロパティ システムを使用して検証と強制化を行う方法の詳細については、「 依存関係プロパティのコールバック」および「検証」 および 「カスタム依存関係プロパティ」を参照してください。
依存関係プロパティ変更イベント
DependencyPropertyChanged イベントにはDependencyPropertyChangedEventArgsイベント データとDependencyPropertyChangedEventHandlerデリゲートがあります。 これらのイベントは、ルーティング イベントではなく、標準の CLR イベントです。
DependencyPropertyChangedEventArgs
は、 EventArgs から派生せず、クラスではなく構造体であるため、通常とは異なるイベント データ レポートの種類です。
DependencyPropertyChanged
イベントの 1 つの例は、IsMouseCapturedChangedです。
DependencyPropertyChanged
イベントは、 RoutedPropertyChanged
イベントよりも少し一般的です。
RoutedPropertyChanged イベント データと同様に、DependencyPropertyChanged イベント データには、 OldValue プロパティと NewValue プロパティが含まれます。 前述の理由から、プロパティ変更イベント ハンドラーを使用してプロパティ値を再度変更しないでください。
プロパティ トリガー
プロパティ変更イベントに密接に関連する概念は、プロパティ トリガーです。 プロパティ トリガーは、スタイルまたはテンプレート内に作成されます。 プロパティ トリガーを使用すると、トリガーが割り当てられているプロパティの値に基づいて条件付き動作を作成できます。
プロパティ トリガーが機能するプロパティは、依存関係プロパティである必要があります。 これは、しばしば読み取り専用の依存関係プロパティであることがあります。 コントロールによって公開される依存関係プロパティの名前が "Is" で始まる場合は、プロパティがプロパティ トリガーとして少なくとも部分的に設計されたことを示します。 この名前付けのプロパティは、多くの場合、読み取り専用 Boolean 依存関係プロパティです。このプロパティの主なシナリオは、コントロールの状態を報告することです。 コントロールの状態がリアルタイム UI に影響する場合、依存関係プロパティはプロパティ トリガー候補になります。
一部の依存関係プロパティには、専用のプロパティ変更イベントがあります。 たとえば、 IsMouseCaptured には、 IsMouseCapturedChanged プロパティの変更イベントがあります。
IsMouseCaptured
プロパティは読み取り専用であり、その値は入力システムによって変更されます。 入力システムは、リアルタイムの変更ごとに IsMouseCapturedChanged
イベントを発生させます。
プロパティ トリガーの制限事項
実際のプロパティ変更イベントと比較して、プロパティ トリガーにはいくつかの制限があります。
プロパティ トリガーは 、プロパティ名とトリガーをアクティブにする特定の値を指定する完全一致ロジックを使用して動作します。 たとえば <Setter Property="IsMouseCaptured" Value="true"> ... </Setter>
です。 プロパティ トリガー構文では、ほとんどのプロパティ トリガーの使用がBooleanプロパティ、または専用の列挙値を受け取るプロパティに限定されます。 各ケースのトリガーを定義できるように、使用可能な値の範囲は管理可能である必要があります。 プロパティ トリガーは、項目数が 0 に達したときなど、特殊な値に対してのみ存在する場合があります。 プロパティ値が 0 などの特定の値から離れたときにアクティブ化するように 1 つのトリガーを設定することはできません。 0 以外のすべてのケースで複数のトリガーを使用する代わりに、コード イベント ハンドラーを実装するか、値が 0 以外の場合にトリガーの状態から切り替える既定の動作を実装することを検討してください。
プロパティ トリガーの構文は、プログラミングの "if" ステートメントに似ています。 トリガー条件が true の場合、プロパティ トリガーの "body" は "run" になります。 プロパティ トリガーの "本文" はコードではなく、マークアップです。 そのマークアップは、1 つ以上の Setter 要素を使用して、スタイルまたはテンプレートが適用されるオブジェクトの他のプロパティを設定するように制限されます。
プロパティ トリガーの "if" 条件にさまざまな可能な値がある場合は、トリガーの外部で Setter
を使用して、同じプロパティ値を既定値に設定することをお勧めします。 そうすることで、トリガー条件が true
されると、トリガー内のセッターが優先されます。そうしないと、トリガー外の Setter
が優先されます。
プロパティ トリガーは、同じ要素の別のプロパティの状態に基づいて 1 つ以上の外観プロパティを変更する必要があるシナリオに役立ちます。
プロパティ トリガーの詳細については、「スタイル設定とテンプレート」を参照してください。
こちらも参照ください
.NET Desktop feedback