web-dev-qa-db-ja.com

PropertyChangedEventHandlerはどのように機能しますか?

これは本当に簡単な質問ですが、4行目が実際に何をしているのか誰かが説明できるのではないかと思っていました。したがって、最初の行はハンドラーにイベントを提供します。ハンドラーがどのような状況でnullを返すのか、または最後の行が何を行うのか、私には本当にわかりません。

ハンドラーにオブジェクトを渡し、どのプロパティを変更した場合、ハンドラーは何をしますか?

PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event

if (handler != null)
{
    handler(this, new PropertyChangedEventArgs(name));
}

これを取得するためにこれを使用したと思います code しかし、それが完全に何をしているのかを理解したいと思います。

16

あなたがちょうどした場合:

PropertyChanged(this, new PropertyChangedEventArgs(name))

イベントNullReferenceExceptionに誰もサブスクライブしていない場合は、PropertyChangedを取得します。これに対処するには、nullチェックを追加します。

if(PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs(name))
}

ここで、マルチスレッドを使用している場合、誰かがnullチェックとイベントの呼び出しの間でサブスクライブを解除できるため、NullReferenceExceptionを取得できます。これを処理するには、イベントハンドラーを一時変数にコピーします。

  PropertyChangedEventHandler handler = PropertyChanged;
  if (handler != null)
  {
    handler(this, new PropertyChangedEventArgs(name));
  }

これで、誰かがイベントから退会した場合でも、一時変数handlerは古い関数を指すため、このコードはNullReferenceExceptionをスローする方法がありません。

ほとんどの場合、代わりにキーワードvarが使用されます。これにより、一時変数の完全なタイプを入力する必要がなくなります。これは、コードで最も頻繁に表示されるフォームです。

  var handler = PropertyChanged;
  if (handler != null)
  {
    handler(this, new PropertyChangedEventArgs(name));
  }
38

PropertyChangedは、インターフェースでの定義に従って、次のように宣言されたイベントです。

_public event PropertyChangedEventHandler PropertyChanged;
_

Events は、サブスクライブしてデリゲート(関数への参照)を追加したり、サブスクライブを解除してデリゲートを削除したりできる、イベントハンドラーのリストの構文シュガーのように定義されています。

ここで、イベント、つまりPropertyChanged(...)を呼び出すと、内部で発生するのは、その内部リスト内のすべてのデリゲートがパラメーターを使用して個別に呼び出されるということです。これにより、イベントのすべてのサブスクライバーにイベントが発生したことが通知されます。

ここで、handler変数を使用する理由は、PropertyChangedがnullになる可能性があるためです。何もサブスクライブしていない場合、イベント(またはイベントハンドラーリスト)の呼び出しは機能しないため、これは、ハンドラーを実際に実行できることを確認するための方法にすぎません。

9
poke

ハンドラーがない場合はhandlerをnullにすることができます subscribed から event まで、4行目は指定されたプロパティ名のイベントを発生させます(すべてのサブスクライブハンドラーを実行します) 。

通常、バインディングを使用すると、WPFフレームワークはPropertyChangedをサブスクライブするため、バインドされたプロパティが変更されるとバインディングを更新できます。

6
H.B.