事件处理程序可以在控件之间传输吗?
从一个控件“窃取”事件处理程序并将其分配给另一个控件的能力多年来一直是编程界争论的话题。虽然问题中建议的语法无效,但在技术上确实可以在运行时在控件之间传输事件处理程序。
反射路由
由于私有和由于 Windows 窗体框架内某些成员的内部性质,反射对于完成此壮举是必要的。通过利用反射,您可以访问原本无法访问的私有字段和属性。
在提供的代码示例中,执行了一系列反射操作:
这有效地将事件处理程序从button1转移到button2。
实现示例
这是中提供的代码的修订版本问题:
using System; using System.ComponentModel; using System.Windows.Forms; using System.Reflection; namespace EventHandlerTransfer { public partial class Form1 : Form { public Form1() { InitializeComponent(); button1.Click += new EventHandler(button1_Click); TransferEventHandler(button1, button2); } private void TransferEventHandler(Control source, Control destination) { // 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 eventsSource = (EventHandlerList)eventsProp.GetValue(source, null); EventHandlerList eventsDestination = (EventHandlerList)eventsProp.GetValue(destination, null); Delegate click = eventsSource[secret]; // Remove it from source, add it to destination eventsSource.RemoveHandler(secret, click); eventsDestination.AddHandler(secret, click); } void button1_Click(object sender, EventArgs e) { MessageBox.Show("Yada"); } } }
结论
虽然以这种方式传输事件处理程序的能力似乎是一个强大的功能,但应谨慎使用。该技术严重依赖反射,这可能会影响性能,并且还可能引入潜在的错误。此外,不建议修改 Windows 窗体框架的私有成员,因为如果框架的未来版本有任何更改,可能会破坏您的应用程序。
以上是事件处理程序可以在 Windows 窗体的控件之间以编程方式传输吗?的详细内容。更多信息请关注PHP中文网其他相关文章!