我想做这样的事情:
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;
是的,在技术上是可行的。因为许多成员是私人的和内部的,所以需要进行反思。启动一个新的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确实非常努力地阻止您执行此操作,那么您就可以理解代码。