none
イベントハンドラ、登録の有無 RRS feed

  • 質問

  • イベントハンドラが登録されているかどうか、登録されていればそのメソッド名って

    取得できたりするんでしょうか?

     

    textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);

    2008年2月22日 8:26

回答

  • どーーーしても外部から判断する必要があるのでしたら、
    イベントの削除・入替方法は?
    のスレッドが参考になると思います。
    # そのスレからリンクされている「イベントの存在チェック」も

     

    また、textBox1_KeyDown がハンドラとして登録されていない場合だけ登録したいということでしたら、以下のように先に解除すればいいです。登録されていないときに "-=" しても、例外が発生することはありませんので。

     

    textBox1.KeyDown -= new KeyEventHandler(textBox1_KeyDown);
    textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);

    2008年2月22日 12:20
  •  ぶるーのさんこんばんは

     リフレクションを使って、以下のコードで取得できます。

     

    サンプルコード

        private static BindingFlags All {
          get {
            return
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.IgnoreCase |
                BindingFlags.Static;
          }
        }

     

        private static MethodInfo GetEventsMethod(Type objType) {
          MethodInfo mi = objType.GetMethod("get_Events", All);
          if ((mi == null) & (objType.BaseType != null))
            mi = GetEventsMethod(objType.BaseType);
          return mi;
        }

     

        private static EventHandlerList GetEvents(object obj) {
          MethodInfo mi = GetEventsMethod(obj.GetType());
          if (mi == null) return null;
          return (EventHandlerList)mi.Invoke(obj, new object[] { });
        }

     

        private static FieldInfo GetEventIDField(Type objType, string eventName) {
          FieldInfo fi = objType.GetField("Event" + eventName, All);
          if ((fi == null) & (objType.BaseType != null))
            fi = GetEventIDField(objType.BaseType, eventName);
          return fi;
        }

     

        private static object GetEventID(object obj, string eventName) {
          FieldInfo fi = GetEventIDField(obj.GetType(), eventName);
          if (fi == null) return null;
          return fi.GetValue(obj);
        }

     

        private void button1_Click(object sender, EventArgs e) {
          EventHandlerList list = GetEvents(textBox1);
          object key = GetEventID(textBox1, "KeyDown");
          Delegate evnt = list[key];
          if (evnt == null) {
            MessageBox.Show("event is not assigned");
          } else {
            Delegate[] el = evnt.GetInvocationList();
            foreach (Delegate evnt1 in el) MessageBox.Show(evnt1.Method.Name);
          }
        }

     

     

    参考URL

    http://www.technewsgroups.net/group/microsoft.public.dotnet.general/topic4196.aspx

     

    2008年2月22日 12:31

すべての返信

  • 自分で作ったクラス内からなら判断できます。

    外部からは無理でしょう。

    2008年2月22日 9:08
  • どーーーしても外部から判断する必要があるのでしたら、
    イベントの削除・入替方法は?
    のスレッドが参考になると思います。
    # そのスレからリンクされている「イベントの存在チェック」も

     

    また、textBox1_KeyDown がハンドラとして登録されていない場合だけ登録したいということでしたら、以下のように先に解除すればいいです。登録されていないときに "-=" しても、例外が発生することはありませんので。

     

    textBox1.KeyDown -= new KeyEventHandler(textBox1_KeyDown);
    textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);

    2008年2月22日 12:20
  •  ぶるーのさんこんばんは

     リフレクションを使って、以下のコードで取得できます。

     

    サンプルコード

        private static BindingFlags All {
          get {
            return
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.IgnoreCase |
                BindingFlags.Static;
          }
        }

     

        private static MethodInfo GetEventsMethod(Type objType) {
          MethodInfo mi = objType.GetMethod("get_Events", All);
          if ((mi == null) & (objType.BaseType != null))
            mi = GetEventsMethod(objType.BaseType);
          return mi;
        }

     

        private static EventHandlerList GetEvents(object obj) {
          MethodInfo mi = GetEventsMethod(obj.GetType());
          if (mi == null) return null;
          return (EventHandlerList)mi.Invoke(obj, new object[] { });
        }

     

        private static FieldInfo GetEventIDField(Type objType, string eventName) {
          FieldInfo fi = objType.GetField("Event" + eventName, All);
          if ((fi == null) & (objType.BaseType != null))
            fi = GetEventIDField(objType.BaseType, eventName);
          return fi;
        }

     

        private static object GetEventID(object obj, string eventName) {
          FieldInfo fi = GetEventIDField(obj.GetType(), eventName);
          if (fi == null) return null;
          return fi.GetValue(obj);
        }

     

        private void button1_Click(object sender, EventArgs e) {
          EventHandlerList list = GetEvents(textBox1);
          object key = GetEventID(textBox1, "KeyDown");
          Delegate evnt = list[key];
          if (evnt == null) {
            MessageBox.Show("event is not assigned");
          } else {
            Delegate[] el = evnt.GetInvocationList();
            foreach (Delegate evnt1 in el) MessageBox.Show(evnt1.Method.Name);
          }
        }

     

     

    参考URL

    http://www.technewsgroups.net/group/microsoft.public.dotnet.general/topic4196.aspx

     

    2008年2月22日 12:31
  • シャノンさん、TH01さん、三輪の牛さん、回答ありがとうございます。

     

    三輪の牛さんが示して頂いた例で、登録しているイベントハンドラの一覧を取得できました。

     

    ありがとうございました。

     

    2008年2月27日 1:27