在按钮单击功能上使用GetMethod和Invoke

时间:2019-01-08 23:01:00

标签: c# invoke buttonclick

我有以下代码:

    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部分时, theMethod为null。我不明白为什么GetMethod无法找到该函数。它在同一个局部类中。这适用于我所有其他功能。

我不能在按钮单击时使用invoke还是参数类型在某种程度上特殊?有没有其他方法可以通过单击按钮来做到这一点?

编辑:

按钮的功能是:

private void buttonClick(object sender, EventArgs e) ...

1 个答案:

答案 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异常。

  • 对于WinForms::如果您确定只通过同一应用程序中其他UI元素的事件处理程序来调用代码,则不必担心线程。否则,您必须将可能操纵UI状态的所有内容(例如对PerformClick()的调用)包装在单独的方法中,并将Invoke(Delegate)与该方法一起使用。通常最容易使用lambda表达式,例如formContainingButton.Invoke(() => button.PerformClick());

(其他框架可能具有处理UI线程的类似结构。)