Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以编程方式单击WPF中的按钮?_C#_.net_Wpf_Button - Fatal编程技术网

C# 如何以编程方式单击WPF中的按钮?

C# 如何以编程方式单击WPF中的按钮?,c#,.net,wpf,button,C#,.net,Wpf,Button,由于WPF中没有按钮.PerformClick()方法,有没有办法通过编程方式单击WPF按钮?如果可以访问源代码,可以通过编程方式“单击”按钮,只需调用按钮的OnClick事件处理程序(或者执行与按钮关联的ICommand,如果您以更WPF-y的方式进行操作) 为什么要这样做?例如,您是在进行某种自动测试,还是试图执行按钮从不同代码段执行的相同操作?WPF采用了与WinForms稍有不同的方法。它们没有将对象的自动化内置到API中,而是为eac提供了一个单独的类负责自动化的对象。在这种情况下,您

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

如果可以访问源代码,可以通过编程方式“单击”按钮,只需调用按钮的OnClick事件处理程序(或者执行与按钮关联的ICommand,如果您以更WPF-y的方式进行操作)


为什么要这样做?例如,您是在进行某种自动测试,还是试图执行按钮从不同代码段执行的相同操作?

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

ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
是一篇关于这个主题的博客文章


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

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

someButton.RaiseEvent(new RoutedEventArgs(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

如前所述,我认为使用MVVM模式单击按钮(单击引发的事件并执行命令)的另一种方法是使用反射调用
OnClick
方法:

this.PowerButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
当使用MVVM命令模式执行按钮功能时(推荐做法),触发按钮效果的简单方法如下:

someButton.Command.Execute(someButton.CommandParameter);

这将使用按钮触发的命令对象,并传递XAML定义的命令参数

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

另一种方法是模拟该行为。下面是我的扩展解决方案,它还通过绑定的命令约束MVVM模式-实现为扩展方法:

公共静态类按钮
{
/// 
///单击按钮。
///这是等同于Windows窗体方法“”的WPF。 ///这模拟了用户通过键盘或鼠标单击按钮时的相同行为:
///1.引发ClickEvent的事件。
///2.1.检查绑定命令是否可以执行,如果命令被绑定,则调用。
///2.2.如果可以执行命令,则将调用,可选绑定参数为p /// /// ///“源”按钮。 ///源按钮 公共静态无效性能单击(此按钮sourceButton) { //检查参数 如果(sourceButton==null) 抛出新ArgumentNullException(nameof(sourceButton)); //1.)引发单击事件 sourceButton.RaiseEvent(新路由EventArgs(System.Windows.Controls.Primitives.ButtonBase.ClickEvent)); //2.)执行命令(如果绑定且可以执行) ICommand boundCommand=sourceButton.Command; if(boundCommand!=null) { 对象参数=sourceButton.CommandParameter; if(boundCommand.CanExecute(参数)==true) boundCommand.Execute(参数); } } }
这并不是解决我问题的唯一方法,但当我尝试这样做时,我发现它没有button.PerformClick()那么简单,所以有点好奇……:)我不得不在同一个项目中点击另一个窗口的菜单,而我的另一个窗口.mnuEntry\u click(我,新窗口.RoutedEventArgs)做到了这一点。真的很简单,斯里克,我没有意识到这一点。对于自动化测试可能非常有用。请注意,该链接上有一条评论,建议使用提供的工厂获取自动化对等点,而不是自己创建一个。谢谢。我努力在我的应用程序中找到正确的名称空间,直到我添加了对
UIAutomationProvider
的引用。然后必须使用System.Windows.Automation.Peers添加
;使用System.Windows.Automation.Provider一行代码:
((IInvokeProvider)(newButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke()
需要注意的一点是调用调用是异步的。这意味着如果您在单元测试中使用它,并且您的下一行是检查单击按钮的预期结果,您可能需要等待。仅供参考,
IInvokeProvider
接口是在
UIAutomationProvider
程序集中定义的t solution只会引发事件。它不会执行与按钮相关的命令(正如Skanaar所说),如果使用XAML,事件将由点击处理程序按照正常方式捕获。+1来自我!我使用的是VB…不确定VB与C#的代码是否不同,但
new RoutedEventArgs(Button.ClickEvent)
对我不起作用。我必须使用
新路由事件(Primitives.ButtonBase.ClickEvent)
。否则,效果很好!要详细说明@EduardoMolteni和Skanaar,您将失去命令以这种方式提供的IsEnabled功能,因此除非您希望所有事件都检查它们是否已启用,否则AutomationPeer工作得更好。这是一种使用子元素的事件在父元素上触发命令的好方法。请注意,这只是一种方法触发按钮在单击时产生的效果。它不会在消息调度队列中生成任何单击事件。对于所有实际情况,这是您所希望的,并将避免不必要的调度程序事件(例如,更多性能)