事件處理程序可以在控制項之間傳送嗎?
從一個控制項「竊取」事件處理程序並將其分配給另一個控制項的能力多年來一直是程式設計界爭論的話題。雖然問題中建議的語法無效,但技術上確實可以在運行時在控制項之間傳輸事件處理程序。
反射路由
由於私有和由於 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中文網其他相關文章!