我在Xaml中定义了一个Button
,如
<Button Name="button1" />
我正在尝试使用反射订阅此Button
的Click
事件。更准确地说,我想调用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);
- 为什么会发生这种情况?
- 有一个修复,我可以申请使它的工作方式,我想要的?
- 我还有别的选择吗?
更新-这是方法的完整版本
private void MyMethod()
{
string testString = "Hello";
Action<object, EventArgs> clickAction = (object sender, EventArgs e) =>
{
MessageBox.Show(testString);
};
Type buttonType = button1.GetType();
EventInfo clickEvent = buttonType.GetEvent("Click");
Delegate clickEventHandler = Delegate.CreateDelegate(clickEvent.EventHandlerType,
null,
clickAction.Method);
clickEvent.AddEventHandler(button1, clickEventHandler);
}
编辑-在评论后重写我的答案:
如果将委托绑定到实例,则可以使此工作。该实例应该是一个类,包含您想要在事件处理程序中使用的所有信息/变量…你创建那个实例,用你想要的值初始化它然后绑定它:
Delegate clickEventHandler = Delegate.CreateDelegate(clickEvent.EventHandlerType, yourinstance, clickAction.Method);
这样委托就有了一个"this",可以用来访问变量…你甚至可以让这些变量代替本地的普通类字段,并将委托绑定到this
。
另一种方法是将这些变量放入"sender object"中,并以这种方式访问它们…