繁体   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