動態分配事件處理程序:可能嗎?
在軟體開發中,事件處理程序對於在 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中文網其他相關文章!