Answers:
WPF采用的方法与WinForms略有不同。他们没有将自动化的对象内置到API中,而是为每个负责自动化的对象都有一个单独的类。在这种情况下,您需要ButtonAutomationPeer
完成此任务。
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
这是有关该主题的博客文章。
注意:IInvokeProvider
接口是在UIAutomationProvider
程序集中定义的。
UIAutomationProvider
。然后不得不添加using System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
接口在UIAutomationProvider
程序集中定义。
就像JaredPar所说的那样,您可以参考Josh Smith的有关自动化的文章。但是,如果您仔细阅读他的文章中的评论,您会发现更优雅的方式来针对WPF控件引发事件
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
我个人更喜欢上面的那种,而不是自动化的同行。
new RoutedEventArgs(Button.ClickEvent)
不适用于我。我不得不用new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
。否则,效果很好!
如果要调用单击事件:
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 });
或使用ToggleButton
如果您可以访问源代码,则以编程方式“单击”按钮的一种方法是简单地调用按钮的OnClick事件处理程序(或者,如果您以更WPF-y的方式执行操作,则执行与按钮关联的ICommand。 )。
你为什么做这个?例如,您是在进行某种自动化测试,还是试图从不同的代码部分执行与按钮执行的相同操作?
将MVVM Command模式用于Button功能时(推荐做法),触发Button效果的简单方法如下:
someButton.Command.Execute(someButton.CommandParameter);
这将使用按钮触发的Command对象,并传递XAML定义的CommandParameter。
Automation API解决方案的问题在于,它需要引用Framework程序集UIAutomationProvider
作为项目/程序包的依赖关系。
另一种方法是模仿行为。以下是我的扩展解决方案,该解决方案还用其绑定命令对MVVM-pattern进行了调节-实现为扩展方法:
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);
}
}
}