153

由于 WPF 中没有button.PerformClick()方法,有没有办法以编程方式单击 WPF 按钮?

4

9 回答 9

199

就像 JaredPar 说的,你可以参考 Josh Smith 的自动化文章。但是,如果您查看他的文章的评论,您会发现针对 WPF 控件引发事件的更优雅的方式

someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));

我个人更喜欢上面的那个而不是自动化同行。

于 2009-04-09T12:21:38.293 回答
143

WPF 在此采用与 WinForms 略有不同的方法。他们没有将对象的自动化内置到 API 中,而是为每个负责自动化它的对象提供了一个单独的类。在这种情况下,您需要ButtonAutomationPeer完成此任务。

ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();

是关于该主题的博客文章。

注意:IInvokeProvider接口是在UIAutomationProvider程序集中定义的。

于 2009-04-08T03:38:08.590 回答
39

如果你想调用点击事件:

SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));

如果您希望按钮看起来像被按下:

typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });

之后就没有压力了:

typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });

或使用切换按钮

于 2011-03-16T12:10:57.153 回答
24
this.PowerButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
于 2012-06-14T07:29:45.360 回答
6

如果您可以访问源,则以编程方式“单击”按钮的一种方法是简单地调用按钮的 OnClick 事件处理程序(或执行与按钮关联的 ICommand,如果您正在以更 WPF-y 的方式执行操作)。

你为什么做这个?例如,您是在进行某种自动化测试,还是尝试执行按钮从不同代码部分执行的相同操作?

于 2009-04-08T03:35:39.877 回答
4

正如Greg D所说,我认为Automation使用 MVVM 模式(引发单击事件并执行命令)单击按钮的替代方法是OnClick使用反射调用该方法:

typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
于 2015-09-03T12:58:51.333 回答
2

在使用MVVM命令模式进行Button功能时(推荐做法),触发Button效果的简单方法如下:

someButton.Command.Execute(someButton.CommandParameter);

这将使用按钮触发的Command对象并传递XAML定义的CommandParameter

于 2019-01-13T21:57:19.953 回答
1

自动化 API 解决方案的问题在于,它需要对框架程序集的引用UIAutomationProvider作为项目/包依赖项。

另一种方法是模仿行为。下面是我的扩展解决方案,它还考虑了 MVVM 模式及其绑定命令 - 实现为扩展方法

public static class ButtonExtensions
{
    /// <summary>
    /// Performs a click on the button.<br/>
    /// This is the WPF-equivalent of the Windows Forms method "<see cref="M:System.Windows.Forms.Button.PerformClick" />".
    /// <para>This simulates the same behaviours as the button was clicked by the user by keyboard or mouse:<br />
    /// 1. The raising the ClickEvent.<br />
    /// 2.1. Checking that the bound command can be executed, calling <see cref="ICommand.CanExecute" />, if a command is bound.<br />
    /// 2.2. If command can be executed, then the <see cref="ICommand.Execute(object)" /> will be called and the optional bound parameter is p
    /// </para>
    /// </summary>
    /// <param name="sourceButton">The source button.</param>
    /// <exception cref="ArgumentNullException">sourceButton</exception>
    public static void PerformClick(this Button sourceButton)
    {
        // Check parameters
        if (sourceButton == null)
            throw new ArgumentNullException(nameof(sourceButton));

        // 1.) Raise the Click-event
        sourceButton.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ButtonBase.ClickEvent));

        // 2.) Execute the command, if bound and can be executed
        ICommand boundCommand = sourceButton.Command;
        if (boundCommand != null)
        {
            object parameter = sourceButton.CommandParameter;
            if (boundCommand.CanExecute(parameter) == true)
                boundCommand.Execute(parameter);
        }
    }
}
于 2020-02-03T08:50:06.800 回答
1

您也可以调用按钮被点击的方法 Button_Click(new object(), new RoutedEventArgs(ButtonBase.ClickEvent)); 花药方式是ButtonName.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent)); 两种方式都需要using System.Windows.Controls.Primitives;

  • Button_Click(new object(), new RoutedEventArgs(ButtonBase.ClickEvent));
  • ButtonName.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
于 2021-08-21T20:19:23.357 回答