是否有可能从一个控件"窃取"一个事件处理程序并将其交给另一个控件?

Mus*_*sis 12 .net c#

我想做这样的事情:

Button btn1 = new Button();
btn1.Click += new EventHandler(btn1_Click);
Button btn2 = new Button();
// Take whatever event got assigned to btn1 and assign it to btn2.
btn2.Click += btn1.Click; // The compiler says no...
Run Code Online (Sandbox Code Playgroud)

其中btn1_Click已在类中定义:

void btn1_Click(object sender, EventArgs e)
{
    //
}
Run Code Online (Sandbox Code Playgroud)

当然,这不会编译("事件'System.Windows.Forms.Control.Click'只能出现在+ =或 - ="的左侧).有没有办法从一个控件获取事件处理程序并在运行时将其分配给另一个控件?如果那是不可能的,重复事件处理程序并在运行时将其分配给另一个控件吗?

有几点:我已经用Google搜索了一段时间,但却发现还没办法做到这一点.大多数尝试过的方法都涉及反射,因此如果您阅读我的问题并认为答案非常明显,请首先尝试在Visual Studio中编译代码.或者,如果答案确实非常明显,请随时给我打电话.谢谢,我真的很期待看到这是否可行.

我知道我可以这样做:

btn2.Click += new EventHandler(btn1_Click);
Run Code Online (Sandbox Code Playgroud)

这不是我在这里寻找的东西.

这也不是我想要的:

EventHandler handy = new EventHandler(btn1_Click);
Button btn1 = new Button();
btn1.Click += handy;
Button btn2 = new Button();
btn2.Click += handy;
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 19

是的,这在技术上是可行的.需要反思,因为许多成员都是私人和内部成员.启动一个新的Windows窗体项目并添加两个按钮.然后:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      button1.Click += new EventHandler(button1_Click);
      // Get secret click event key
      FieldInfo eventClick = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);
      object secret = eventClick.GetValue(null);
      // Retrieve the click event
      PropertyInfo eventsProp = typeof(Component).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
      EventHandlerList events = (EventHandlerList)eventsProp.GetValue(button1, null);
      Delegate click = events[secret];
      // Remove it from button1, add it to button2
      events.RemoveHandler(secret, click);
      events = (EventHandlerList)eventsProp.GetValue(button2, null);
      events.AddHandler(secret, click);
    }

    void button1_Click(object sender, EventArgs e) {
      MessageBox.Show("Yada");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如果这让你确信微软真的很难阻止你这样做,你就会理解代码.