Область применения при использовании обработчиков событий и отражений - PullRequest
1 голос
/ 31 июля 2011

У меня есть Button, определенный в Xaml как

<Button Name="button1" />

Я пытаюсь подписаться на событие Click этого Button, используя Reflection.Точнее, я хочу вызвать 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);
  • Почему это происходит?
  • Есть ли исправление Iможно применить, чтобы заставить его работать так, как я хочу?
  • Есть ли у меня другой вариант?

Обновление - это то, как метод выглядит полностью

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

1 Ответ

1 голос
/ 31 июля 2011

РЕДАКТИРОВАТЬ - переписать мой ответ после комментариев:

Вы можете сделать это, если привязываете делегата к экземпляру. этот экземпляр должен быть классом, содержащим всю информацию / переменную, которую вы хотите использовать из вашего обработчика событий ... вы создаете этот экземпляр, инициализируете его нужными значениями и затем связываете его:

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

таким образом, у делегата есть «this», которое можно использовать для доступа к переменным ... Вы могли бы даже сделать эти переменные вместо локальных просто полями класса и связать делегат с this.

другой вариант - поместить эти переменные в «объект отправителя» и получить к ним доступ таким образом ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...