簡體   English   中英

通過反思獲得活動

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM