我有以下代码:
object[] parameters = { new object(), new EventArgs() };
Type[] type = new[] { typeof(object), typeof(EventArgs)};
MethodInfo theMethod = thisType.GetMethod("button_Click", type);
object result = theMethod.Invoke(this, parameterList);
当我进入theMethod.Invoke部分时,我不能在按钮单击时使用invoke还是参数类型在某种程度上特殊?有没有其他方法可以通过单击按钮来做到这一点?
编辑:
按钮的功能是:
private void buttonClick(object sender, EventArgs e) ...
答案 0 :(得分:1)
您的反射方法不起作用的原因是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);
为了找到解决问题的最佳方法,请问自己以下问题:
首先:您真的需要使用反射吗?如果您可以控制要与之交互的表单的源代码,即可以在form类中添加内容,那么您应该跳过反射内容,并添加用于与按钮交互的公共方法。
第二:您是要调用特定方法(“ buttonClick”,它也恰好是事件处理程序),还是要正确模拟用户操作,以使UI框架意识到“点击”并对其进行处理(调用所有附加的事件处理程序,而不管方法名称如何,等等)?
如何最好地模拟用户操作取决于您与之交互的框架:
如果框架为此提供了特定的方法,请调用该方法(如果绝对需要,可以通过反射)。 WinForms按钮具有PerformClick()方法。
没有单独方法(例如WebForms)的框架通常具有可以调用的OnClicked方法。这可能需要使用反射,因为这些方法通常是受保护的而不是公共的。
第三步::如果要处理Windows GUI框架(而不是Web框架),则可能还需要确保从代码启动的UI操作在正确的线程上执行,否则您可能会遇到意外的InvalidOperationException
异常。
PerformClick()
的调用)包装在单独的方法中,并将Invoke(Delegate)与该方法一起使用。通常最容易使用lambda表达式,例如formContainingButton.Invoke(() => button.PerformClick());
(其他框架可能具有处理UI线程的类似结构。)