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



我在Xaml中定义了一个Button,如

<Button Name="button1" />

我正在尝试使用反射订阅此ButtonClick事件。更准确地说,我想调用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"中,并以这种方式访问它们…

相关内容

  • 没有找到相关文章

最新更新