使用事件处理程序和反射时的范围

时间:2011-07-31 01:14:42

标签: c# .net wpf events reflection

我在Xaml中定义了Button,如

<Button Name="button1" />

我正在尝试使用Reflection订阅此Click的{​​{1}}事件。更确切地说,我想调用一个Button并在事件处理程序中,我想从范围之外访问一个局部变量,如下所示

Action<object, EventArgs>

如果我这样做,则会显示string testString = "Hello"; Action<object, EventArgs> clickAction = (object sender, EventArgs e) => { MessageBox.Show(testString); };

Hello

类似地,如果我只是订阅这样的clickAction.Invoke(null, null); 事件,则会显示Click

Hello

但是,如果我使用反射来订阅button1.Click += (sender, e) => { MessageBox.Show(testString); }; 的活动,我将无法访问AddEventHandler并在事件处理程序中获得testString

NullReferenceException
  • 为什么会这样?
  • 我可以申请修复以使其按照我想要的方式工作吗?
  • 我还有其他选择吗?

更新 - 这就是方法完整的

Type buttonType = button1.GetType();
EventInfo clickEvent = buttonType.GetEvent("Click");
Delegate clickEventHandler = Delegate.CreateDelegate(clickEvent.EventHandlerType,
                                                     null,
                                                     clickAction.Method);
clickEvent.AddEventHandler(button1, clickEventHandler);

1 个答案:

答案 0 :(得分:1)

编辑 - 在评论后重写我的回答:

如果将委托绑定到实例,则可以使其工作。该实例应该是一个包含您要在事件处理程序中使用的所有信息/变量的类... 您创建该实例,使用您想要的值初始化它,然后绑定它:

Delegate clickEventHandler = Delegate.CreateDelegate(clickEvent.EventHandlerType, yourinstance, clickAction.Method);

这样委托有一个“this”,可用于访问变量...... 你甚至可以创建那些变量而不是本地的普通类字段,并将委托绑定到this

另一种选择是将thos变量放入“发送者对象”并以这种方式访问​​它们......