在软件开发中,有时可能需要从一个控件分配一个事件处理程序在运行时到另一个。本文深入探讨了此类操作的可行性,探讨了潜在的注意事项和可用的解决方法。
原始问题试图找到一种方法来传输分配的事件处理程序在运行时从一个按钮 (btn1) 到另一个按钮 (btn2)。然而,编译器认为这个赋值无效,指出事件处理程序只能分配到赋值的左侧。
虽然直接的方法遇到了编译器错误事实证明,在运行时窃取事件处理程序确实是可能的,尽管有一个警告:需要反射。反射授予对对象的私有和内部成员的访问权限,这些成员通常是不可访问的。
解决方案涉及几个步骤:
以下代码演示了事件窃取技术:
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"); } } }
As代码表明,窃取事件处理程序的过程相当复杂,需要对内部对象结构有复杂的了解。很明显,微软已经做出了巨大的努力来阻止直接访问这些结构,这表明应该明智地使用这项技术。
以上是C# 中的事件处理程序可以在运行时被窃取和重新分配吗?的详细内容。更多信息请关注PHP中文网其他相关文章!