[英]Getting event via reflection
我試圖通過反射獲取按鈕的Click事件,這是我的代碼:
Assembly assem = Assembly.GetExecutingAssembly();
Type tExForm = btnSave.GetType();
Object exFormAsObj = Activator.CreateInstance(tExForm);
EventInfo evClick = tExForm.GetEvent("Click");
Type tDelegate = evClick.EventHandlerType;
MethodInfo miHandler=
btnSave.GetType().GetMethod("Click",
BindingFlags.NonPublic | BindingFlags.Instance);
Delegate d = Delegate.CreateDelegate(tDelegate, btnSave, miHandler);
MethodInfo addHandler = evClick.GetAddMethod();
Object[] addHandlerArgs = { d };
addHandler.Invoke(exFormAsObj, addHandlerArgs);
但是miHandler
變量始終為null!
注意我關注的主要問題是如何在運行時調用特定控件的事件,有沒有辦法? 例如,我想選擇當用戶按F1時觸發哪個點擊事件。
根據問題下方的其他評論,真正的目標是通過反思提出一個事件。
我首先要說的是 , 這幾乎是一個非常可怕的想法 。 它容易出錯並且易碎; 它只是在尋找錯誤。 我推薦的是擁有許多事件處理程序(按鈕點擊處理程序,按鍵事件處理程序等)都只是調用一個常用的方法來完成你想要的實際操作。
話雖如此,這是怎么做的。 反思總是很脆弱,這是它的一個主要例子 - 你必須依賴.NET中事件如何工作的當前實現細節,明天可能會改變,這將停止工作。 您將獲得一個存儲在該對象上的私有字段,該字段保存對所有訂閱事件處理程序的引用,遍歷每個字段並調用它。 您還需要手動創建將傳遞的參數(如EventArgs):
var eventArgs = EventArgs.Empty; //replace with real args
var eventInfo = tExForm.GetType().GetEvent("Click", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
var eventDelegate = (MulticastDelegate)tExForm.GetType().GetField("Click", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tExForm);
if (eventDelegate != null)
{
foreach (var handler in eventDelegate.GetInvocationList())
{
handler.Method.Invoke(handler.Target, new object[] { tExForm, eventArgs });
}
}
您應該包含BindingFlag.FlattenHierarchy
因為Click
是在Control
上定義的,而不是Button
。
EventInfo miHandler =
btnSave.GetType(). GetEvent("Click",
BindingFlags.FlattenHierarchy | BindingFlags.Instance);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.