代码之家  ›  专栏  ›  技术社区  ›  Florian

订阅带有反射的事件

  •  8
  • Florian  · 技术社区  · 14 年前

    class Trace
    {
        void WriteTrace()
        {
            Console.WriteLine("Trace !");
        }
    }
    

    我希望这个类订阅一个事件,例如表单控件的加载事件。控件和事件是动态定义的,因此我想使用反射来执行此操作我正在尝试类似的操作:

    在我的类跟踪中,我有一个方法:

    public void SubscribeEvent (Control control)
    {
            if (type.IsAssignableFrom(control.GetType()))
            {
                Trace test = this;
                MethodInfo method = typeof(Trace).GetMethod("WriteTrace");
    
                // Subscribe to the event
                EventInfo eventInfo = control.GetType().GetEvent("Load"); // We suppose control is a form 
                Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, control, method); // ERROR : Error binding to target method
    
            }
        }
    }
    

    最后一行有错误:绑定到目标方法时出错。我的代码片段怎么了?

    谢谢您!

    :Ok,不再有错误,但当从窗体引发事件“Load”时,不会调用方法WriteTrace(我已放置断点,但未到达)。为什么?

    很抱歉编辑,它工作得很好:)

    2 回复  |  直到 14 年前
        1
  •  9
  •   Pieter van Ginkel    14 年前

    稍加改动,我就可以执行您的示例了。

    首先,关于 Trace 必须有不同的签名才能与 EventHandler

    public class Trace
    {
        public void WriteTrace(object sender, EventArgs e)
        {
            Console.WriteLine("Trace !");
        }
    }
    

    接下来,对 SubscribeEvent :

    public void SubscribeEvent(Control control)
    {
        if (typeof(Control).IsAssignableFrom(control.GetType()))
        {
            Trace test = this;
            MethodInfo method = typeof(Trace).GetMethod("WriteTrace");
    
            EventInfo eventInfo = control.GetType().GetEvent("Load");
    
            // Create the delegate on the test class because that's where the
            // method is. This corresponds with `new EventHandler(test.WriteTrace)`.
            Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, test, method);
            // Assign the eventhandler. This corresponds with `control.Load += ...`.
            eventInfo.AddEventHandler(control, handler);
        }
    }
    

    我希望这能有帮助。

        2
  •  1
  •   Mark Heath    14 年前

    第一个问题是Trace.WriteTrace方法签名与窗体不匹配。加载事件处理程序语法

    void WriteTrace(object sender, EventArgs e)
    {
        Console.WriteLine("Trace !");
    }
    

    另外,对CreateDelegate的调用需要传递跟踪对象,而不是控件对象:

    Trace test = this;
    MethodInfo method = typeof(Trace).GetMethod("WriteTrace");
    
    // Subscribe to the event
    EventInfo eventInfo = control.GetType().GetEvent("Load"); // We suppose control is a form 
    
    Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, method); // ERROR : Error binding to target method
    eventInfo.AddEventHandler(control, handler);