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