小编典典

是否可以从一个控件“窃取”事件处理程序并将其提供给另一个控件?

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...

在类中已定义btn1_Click的位置:

void btn1_Click(object sender, EventArgs e)
{
    //
}

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

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

我知道我可以这样做:

btn2.Click += new EventHandler(btn1_Click);

那不是我在这里要找的东西。

这也不是我要找的东西:

EventHandler handy = new EventHandler(btn1_Click);
Button btn1 = new Button();
btn1.Click += handy;
Button btn2 = new Button();
btn2.Click += handy;

阅读 261

收藏
2020-05-19

共1个答案

小编典典

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

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");
    }
  }
}

如果这使您确信Microsoft确实非常努力地阻止您执行此操作,那么您就可以理解代码。

2020-05-19