Причина, по которой ваш подход к отражению не работает, заключается в том, что Type.GetMethod (String, Type []) будет возвращать только открытые методы, а ваш buttonClick
метод является закрытым.
Чтобы получить доступ к закрытым методам с помощью отражения, вы должны использовать одну из перегрузок, которая принимает BindingFlags
и включает BindingFlags.NonPublic
вместе с BindingFlags.Instance
и / или BindingFlags.Static
, в зависимости от того, что вы хотите включить в поиск.
Очень часто, особенно когда вы имеете дело с обработчиками событий, встречаются только методы с тем же именем. В таких случаях нет необходимости указывать типы параметров при вызове GetMethod. Вместо этого вы можете использовать более простой GetMethod (String, BindingFlags) :
MethodInfo theMethod = thisType
.GetMethod("buttonClick", BindingFlags.NonPublic | BindingFlags.Instance);
Лучшие способы имитации нажатия кнопки
Чтобы найти наилучший подход к вашей проблеме, задайте себе следующие вопросы:
Первый: Вам действительно нужно использовать отражение? Если у вас есть контроль над исходным кодом для формы, с которой вы взаимодействуете, т. Е. С возможностью добавления объектов в класс формы, то вам следует пропустить материал отражения и добавить открытый метод для взаимодействия с кнопкой.
Секунда: Вы просто хотите вызвать определенный метод ("buttonClick", который также является обработчиком событий), или вы хотите правильно имитировать действие пользователя , чтобы инфраструктура пользовательского интерфейса узнала об «щелчке» и обработала его (вызывая все подключенные обработчики событий, независимо от имен методов и т. д.)?
Способ наилучшего моделирования действий пользователя зависит от среды, с которой вы взаимодействуете:
Если в каркасе есть специальный метод для этого, вызовите этот метод (возможно, с помощью рефлексии, если вам абсолютно необходимо). Кнопки WinForms имеют метод PerformClick () .
Фреймворки, у которых нет отдельного метода, например, WebForms, обычно имеют метод OnClicked, который вы можете вызвать. Это может потребовать использования отражения, поскольку эти методы часто защищены вместо общедоступных.
Третье: Если вы имеете дело с каркасом Windows GUI (а не с веб-каркасом), вам также может понадобиться убедиться, что манипуляции с пользовательским интерфейсом, инициированные вашим кодом, выполняются в правильном потоке, в противном случае вы можете получить неожиданные InvalidOperationException
исключения.
- Для WinForms: Если вы уверены, что ваш код будет вызываться только через обработчики событий других элементов пользовательского интерфейса в том же приложении, вам не нужно беспокоиться о потоках. В противном случае вы должны обернуть все, что может потенциально манипулировать состоянием пользовательского интерфейса (например, вызовы
PerformClick()
), в отдельный метод и использовать Invoke (Delegate) с этим методом. Часто это проще всего использовать с лямбда-выражением, например, formContainingButton.Invoke(() => button.PerformClick());
(Другие структуры могут иметь аналогичные конструкции для работы с потоками пользовательского интерфейса.)