开发者

Scope when using Event Handlers and Reflection

开发者 https://www.devze.com 2023-03-24 16:35 出处:网络
I have a Button defined in Xaml like <Button Name=\"button1\" /> I\'m trying to subscribe to the Click event of this Button using Reflection. More precisely I want to invoke an Action<obje

I have a Button defined in Xaml like

<Button Name="button1" />

I'm trying to subscribe to the Click event of this Button using Reflection. More precisely I want to invoke an Action<object, EventArgs> and inside the event handler I want to access a local variable from outside of the scope like this

s开发者_JAVA技巧tring testString = "Hello";
Action<object, EventArgs> clickAction = (object sender, EventArgs e) =>
{
    MessageBox.Show(testString);
};

If I do this, Hello is displayed

clickAction.Invoke(null, null);

Similar, if I just subscribe to the Click event like this, Hello is displayed

button1.Click += (sender, e) => 
{
    MessageBox.Show(testString);
};

But if I use reflection to subscribe to the event with AddEventHandler, I'm unable to access testString and I get a NullReferenceException in the event handler.

Type buttonType = button1.GetType();
EventInfo clickEvent = buttonType.GetEvent("Click");
Delegate clickEventHandler = Delegate.CreateDelegate(clickEvent.EventHandlerType,
                                                     null,
                                                     clickAction.Method);
clickEvent.AddEventHandler(button1, clickEventHandler);
  • Why does this happend?
  • Is there a fix I can apply to make it work the way I want?
  • Do I have another option?

Update - This is what the Method looks like in full

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);
}


EDIT - rewriting my answer after the comments:

you can make this work if you bind the delegate to an instance. that instance should be a class containing all information/variable you want to use from within your event handler... you create that instance, initialize it with the values you want and then bind it:

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

this way the delegate has a "this" which can be used to access the variables... you could even make those variables instead of local just plain class fields and bind the delegate to this.

another option would be to put thos variables into the "sender object" and access them that way...

0

精彩评论

暂无评论...
验证码 换一张
取 消