首页 > 解决方案 > 在按钮单击功能上使用 GetMethod 和 Invoke

问题描述

我有以下代码:

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

我不能在按钮单击时使用调用,还是参数类型在某些方面是特殊的?是否有另一种方法可以通过单击按钮来做到这一点?

编辑:

该按钮的功能是:

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

标签: c#invokebuttonclick

解决方案


您的反射方法不起作用的原因是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”,它也恰好是一个事件处理程序),还是你想正确模拟用户操作,以便 UI 框架意识到“点击”并处理它(调用所有附加的事件处理程序,不管方法名称等)?

如何最好地模拟用户操作取决于您正在与之交互的框架:

  • 如果框架对此有特定的方法,请调用该方法(可能通过反射,如果你必须这样做的话)。WinForms 按钮具有PerformClick()方法。

  • 没有单独方法的框架(如 WebForms)通常具有您可以调用的 OnClicked 方法。这可能需要使用反射,因为这些方法通常是受保护的而不是公开的。

第三:如果您正在处理 Windows GUI 框架(而不是 Web 框架),您可能还需要确保从您的代码启动的 UI 操作在正确的线程上执行,否则您可能会遇到意外InvalidOperationException异常。

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

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


推荐阅读