通过反思获得活动

我试图通过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);