首页 >后端开发 >C++ >C# 中的事件处理程序可以动态重新分配吗?

C# 中的事件处理程序可以动态重新分配吗?

Susan Sarandon
Susan Sarandon原创
2024-12-31 02:46:09785浏览

Can Event Handlers Be Dynamically Reassigned in C#?

动态分配事件处理程序:可能吗?

在软件开发中,事件处理程序对于在 UI 元素之间建立事件驱动的交互至关重要和底层代码。然而,出现了一个常见问题:是否可以“窃取”分配给一个控件的事件处理程序并将其分配给另一个控件?

编译器的限制

分配时使用 = 运算符的事件处理程序,编译器会限制已分配的事件处理程序的分配。尝试为 btn2 重用分配给 btn1 的事件处理程序将导致编译器错误。

反思:解决方案路径

尽管编译器有限制,但这确实是可能的使用反射在运行时传输事件处理程序。此方法需要直接访问控制类的私有和内部成员。

代码示例

考虑以下代码片段:

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

在此代码中,检索秘密内部事件密钥并用于访问 btn1 的事件处理程序列表。然后,事件处理程序从 btn1 中删除并添加到 btn2。

复杂性和限制

虽然反射提供了一种传输事件处理程序的方法,但需要注意的是这种方法很复杂,应谨慎使用。它涉及访问控制类的内部实现细节,这些细节可能会在框架的不同版本中发生变化。

以上是C# 中的事件处理程序可以动态重新分配吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn