結構長い間、C#とVBやってるのですが、つい最近知りました。(恥
なので、メモメモ。
イベントの登録には、2種類の方法があります。
(1) ノーマルな方法
public event EventHandler Event1;
上記のやり方は、参考書等でもおなじみの方法ですね。
でも、イベントの定義方法としては、もう一つやり方があります。
(2) 追加と解除のタイミングを制御する方法
public event EventHandler Event1{ add{ Events.AddHandler(); } remove{ Events.RemoveHandler(); } }
addブロックの部分で、イベントの登録。removeブロックで、イベントの解除
のロジックを記述します。こちらの方法の場合は、自分自身で、イベントの設定・解除を
記述しないといけませんが、こちらの場合は自前でいろいろ制御が行えます。
(ログ出力や、データベースアクセスなど)
Eventsプロパティは、System.ComponentModel.Componentクラスに定義されているプロパティです。
中身は、以下のクラスのインスタンスに処理を委譲しています。
System.ComponentModel.EventHandlerList
カスタムコントロールや、カスタムコンポーネントを作成している場合は予めControlかComponentを継承している
ので、そのままEventsプロパティが存在しますが、普通のクラスに対して(2)の方法でイベント処理を記述する場合は
そのクラス内で、直接EventHandlerListのインスタンスを保持するようにします。
class Hoge {
EventHandlerList _eventList;
...
}
以下、サンプルです。
(1)の方法のサンプル。
#region EventSettingSamples-01 public class EventSettingSamples01: IExecutable{ class Sample{ public Sample(){ Events = new EventHandlerList(); } public EventHandlerList Events{ get; set; } public event EventHandler TestEvent; public void FireEvents(){ if (TestEvent != null) { TestEvent(this, EventArgs.Empty); } } } public void Execute(){ Sample obj = new Sample(); EventHandler handler = (s, e) => { Console.WriteLine("event raised."); }; obj.TestEvent += handler; obj.FireEvents(); obj.TestEvent -= handler; obj.FireEvents(); } } #endregion
(2)の方法のサンプル.
#region EventSettingSamples-02 public class EventSettingSamples02 : IExecutable{ class Sample{ object _eventTarget = new object(); public Sample(){ Events = new EventHandlerList(); } public EventHandlerList Events{ get; set; } public event EventHandler TestEvent{ add{ Console.WriteLine("add handler."); Events.AddHandler(_eventTarget, value); } remove{ Console.WriteLine("remove handler."); Events.RemoveHandler(_eventTarget, value); } } public void FireEvents(){ EventHandler handler = Events[_eventTarget] as EventHandler; if (handler != null) { handler(this, EventArgs.Empty); } } } public void Execute(){ Sample obj = new Sample(); EventHandler handler = (s, e) => { Console.WriteLine("event raised."); }; obj.TestEvent += handler; obj.FireEvents(); obj.TestEvent -= handler; obj.FireEvents(); } } #endregion
(1)のサンプルの場合には、"event raised"としか表示されませんが、(2)のサンプルの場合には
"add ...", "event raised", "remove ..."と表示されます。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ