読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET 絡みのメモを公開しています。

イベントの設定及び解除時に独自の処理を行えるようにする。(Events, System.ComponentModel.Component, EventHandlerList, AddHandler, RemoveHandler)

C#


結構長い間、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 ..."と表示されます。

================================
過去の記事については、以下のページからご参照下さい。