怎么从一个EventInfo和其target中反射出EventHandler??

解决方案 »

  1.   

    或者说 怎么反射出 EventHandler 中Add的Delegate
      

  2.   

    其实我想做的就是 动态生成一个控件,然后让这个控件的Click事件等于之前一个特定控件的Click
    直接
    void LinkEvent(Control eventCtrl, Control ctrl, string eventName)
            {
                pic.Click = eventCtrl.Click;
            }就报错   事件“System.Windows.Forms.Control.Click”只能出现在 += 或 -= 的左边
    void LinkEvent(Control eventCtrl, Control ctrl, string eventName)
            {
                try
                {
                    BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                    Type myTypeBindingFlags = typeof(System.Windows.Forms.Button);
                    EventInfo ei = eventCtrl.GetType().GetEvent(eventName, myBindingFlags);                if (ei != null)
                    {
                        
                        Delegate dele = Delegate.CreateDelegate(typeof(EventHandler), eventCtrl, ???????);                    if (dele.GetInvocationList().Length > 0)
                        {
                            ei.AddEventHandler(ctrl, dele);
                        }
                    }
                }
                catch// (Exception)
                {
    #if DEBUG
                    throw;
    #endif
                }
            }???的地方实在不知道怎么写了...难道思路错了??
      

  3.   

    EventInfo   vEventInfo   =   typeof(Button).GetEvent( "Click "); 
    vEventInfo.AddEventHandler(button1,   
     Delegate.CreateDelegate(vEventInfo.EventHandlerType,   this,   "method1 ")); 
     
     
      

  4.   

    4楼 你没有理解我的意思void LinkEvent(Control eventCtrl, Control ctrl, string eventName)
    {
         ctrl.Click = eventCtrl.Click;
    }
    其实我要的是类似这样的效果,当然上面的代码是错的我不知道   eventCtrl.Click 中绑定的是那些EventHandler
    所以要把eventCtrl.Click 中的EventHandler反射出来的
    然后再绑定到 ctrl.Click中
      

  5.   

    4楼 你没有理解我的意思void LinkEvent(Control eventCtrl, Control ctrl, string eventName)
    {
         ctrl.Click = eventCtrl.Click;
    }
    其实我要的是类似这样的效果,当然上面的代码是错的我不知道   eventCtrl.Click 中绑定的是那些EventHandler
    所以要把eventCtrl.Click 中的EventHandler反射出来的
    然后再绑定到 ctrl.Click中
      

  6.   

    Control.Click有点特殊,你还是记录下来好了。
    Button1.Click += Button1_Click;
    Button2.Click += Button1_Click;
      

  7.   

    void LinkEvent(Control eventCtrl, Control ctrl, string eventName)
    {
        try
        {
            BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            EventInfo ei = eventCtrl.GetType().GetEvent(eventName, myBindingFlags);
            //根据eventCtrl和eventName得到 EventInfo 
            if (ei != null)
            {
                
                Delegate dele = Delegate.CreateDelegate(typeof(EventHandler), eventCtrl, ei.囧囧囧囧);
                //将eventCtrl中的EventInfo 反射出来
                if (dele.GetInvocationList().Length > 0)
                {
                    ei.AddEventHandler(ctrl, dele);//添加到ctrl中去
                }
            }
        }
        catch// (Exception)
        {
    #if DEBUG
            throw;
    #endif
        }
    }现在我就是不知道 囧囧囧囧 这个位置要写入什么
      

  8.   

    http://blog.csdn.net/wuyazhe/archive/2010/09/29/5915151.aspx但对于Click却不适用,因为Control.Click注册方式很特别。
      

  9.   

    EventHandler是个delegate好象
      

  10.   

    很难
    对于这种自定义实现add/remove的事件没有统一的方法可用
    建议用工具(如 Red Gate's .NET Reflector)把源码反出来,照着类内部的方式来实现,当然因为可访问性的问题一堆反射是少不了的
      

  11.   

    我也试过反射Field但是非常奇怪的是 所有Control的Event都不算Field
    无法用GetField或者GetFields来获取,BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
      

  12.   

    我也试过反射Field但是非常奇怪的是 所有Control的Event都不算Field
    无法用GetField或者GetFields来获取,BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
      

  13.   

    因为不是event EventHandler Click;而是event EventHandler Click
    {
      add { ... }
      remove { ... }
    }上面那个编译器会生成 field,下面那个不会
      

  14.   


    Delegate GetEventDelegate(Control ctrl, string eventName)
            {
                Type t = ctrl.GetType();            FieldInfo fi = GetEventField(t, eventName);            while (fi == null)
                {
                    t = t.BaseType;
                    if (t == null) return null;
                    fi = GetEventField(t, eventName); ;
                }            BindingFlags bf = BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;
                PropertyInfo pi = ctrl.GetType().GetProperty("Events", bf);            if (pi == null) return null;
                
                EventHandlerList eventList = pi.GetValue(ctrl, null) as EventHandlerList;
                if (eventList == null) return null;
                
                Delegate dele = eventList[fi.GetValue(null)];            return dele;
            }        FieldInfo GetEventField(Type t, string eventName)
            {
                BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase;
                FieldInfo fi = t.GetField("Event" + eventName, bf) ?? t.GetField("Event_" + eventName, bf);
                if (fi == null)
                {
                    if (eventName.EndsWith("changed", StringComparison.OrdinalIgnoreCase))
                    {
                        return GetEventField(t,eventName.Remove(eventName.Length - 7));
                    }
                }
                return fi;
            }        void LinkEvent(Control eventCtrl, Control ctrl, string eventName)
            {
                try
                {
                    BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;                EventInfo ei = eventCtrl.GetType().GetEvent(eventName, myBindingFlags);                Delegate dele = GetEventDelegate(eventCtrl, eventName);                
                    if (dele != null)
                    {
                        if (dele.GetInvocationList().Length > 0)
                        {
                            ei.AddEventHandler(ctrl, dele);
                        }
                    }
                }
                catch// (Exception)
                {
    #if DEBUG
                    throw;
    #endif
                }
            }我找到方法了,目前碰到2个问题,
    首先是 一般事件 会在Control中表示为 Event*这样的静态字段模式 比如Click 会表示成 EventCilck
    但是 有些*Changed 事件,比如TextChanged 会表示 EventText
    又有一些 Changed 事件不会还有一些特殊的事件会在本身控件的类中表示为 EVENT_* 这样的形式
    所以写了一些简单的兼容,不知道还有没有其他的情况???