Since there's no button.PerformClick()
method in WPF, is there a way to click a WPF button programmatically?
10 Answers
Like JaredPar said you can refer to Josh Smith's article towards Automation. However if you look through comments to his article you will find more elegant way of raising events against WPF controls
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
I personally prefer the one above instead of automation peers.

- 66,056
- 18
- 147
- 180

- 2,805
- 1
- 17
- 10
-
32The RaiseEvent solution only raises the event. It does not execute the Command associated with the Button (as Skanaar say) – Eduardo Molteni Jan 18 '10 at 10:30
-
4If you use XAML eg , the event will be caught by the on click handler as per normal. +1 from me! – metao Jun 03 '10 at 03:59
-
6I'm using VB...not sure if the code is different for VB verses C#, but `new RoutedEventArgs(Button.ClickEvent)` didn't work for me. I had to use `new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)`. Otherwise, works great! – Mageician Mar 08 '12 at 17:25
-
4To elaborate on @EduardoMolteni and Skanaar, you lose the IsEnabled functionality given by Commands this way, so unless you want all of your events to check if they are enabled, the AutomationPeer works better. – Justin Pihony Jul 17 '12 at 17:19
WPF takes a slightly different approach than WinForms here. Instead of having the automation of a object built into the API, they have a separate class for each object that is responsible for automating it. In this case you need the ButtonAutomationPeer
to accomplish this task.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Here is a blog post on the subject.
Note: IInvokeProvider
interface is defined in the UIAutomationProvider
assembly.
-
2Slick, I wasn't aware of this. Could be very useful for automated testing. Note that there's a comment on that link which suggests using a provided factory to get the automation peer instead of creating one yourself. – Greg D Apr 08 '09 at 11:46
-
2If this is a ToggleButton: button.IsChecekd = false/true; seems to be enough – robi-y Apr 29 '13 at 08:29
-
1I would change the second line to `IInvokeProvider invokeProv = (IInvokeProvider)peer.GetPattern( PatternInterface.Invoke );` since you know that this cast should always be valid. – MEMark Dec 13 '13 at 15:39
-
7Thanks for this. I struggled to find the correct namespaces in my app, until I added a reference to `UIAutomationProvider`. Then had to add `using System.Windows.Automation.Peers; using System.Windows.Automation.Provider;` – sergeantKK Nov 28 '14 at 09:37
-
5A one-liner for the inclined: `((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();` – Danny Beckett Jan 07 '15 at 15:24
-
3One thing to note is that the Invoke call is asynchronous. That means if you are using it in a unit test and your next line is to check the expected result of clicking the button, you might have to wait. – denver Apr 22 '15 at 18:32
-
4Just for reference, the `IInvokeProvider` interface is defined in the `UIAutomationProvider` assembly. – Steven Rands Jan 31 '17 at 15:09
-
1
-
Slightly off from the question, but you could move all the actions you are accomplishing into a function and then call that function instead of clicking the button. This was suggested in the comments of the blog linked above and is what I was looking for (and didn't think of). – George May 16 '23 at 17:06
if you want to call click event:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
And if you want the button looks like it is pressed:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
and unpressed after that:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
or use the ToggleButton

- 1,379
- 10
- 17
this.PowerButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));

- 24,731
- 12
- 95
- 110

- 261
- 3
- 2
As Greg D said, I think that an alternative to Automation
to click a button using the MVVM pattern (click event raised and command executed) is to call the OnClick
method using reflection:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
-
This is a good way to use an event from a child element to fire a command on a parent. – Cool Blue Jan 28 '17 at 07:09
One way to programmatically "click" the button, if you have access to the source, is to simply call the button's OnClick event handler (or Execute the ICommand associated with the button, if you're doing things in the more WPF-y manner).
Why are you doing this? Are you doing some sort of automated testing, for example, or trying to perform the same action that the button performs from a different section of code?

- 43,259
- 14
- 84
- 117
-
It's not the only solution to my problem, but when I tried to do this, I found that it's not as easy as button.PerformClick(), so just a bit curious... :) – tghoang Apr 08 '09 at 04:09
-
I had to click on the menu of another window in the same project, and MyOtherWindow.mnuEntry_Click(Me, New Windows.RoutedEventArgs) did it. Really simple. – Andrea Antonangeli Jun 23 '17 at 16:39
When using the MVVM Command pattern for Button function (recommended practice), a simple way to trigger the effect of the Button is as follows:
someButton.Command.Execute(someButton.CommandParameter);
This will use the Command object which the button triggers and pass the CommandParameter defined by the XAML.

- 145
- 1
- 4
-
One note, this only triggers the *effect* the button will have if clicked. It does not generate any click events in the message dispatching queue. For all practical cases this is what you will desire and will avoid unnecessary dispatcher events (e.g. more performant) but if your actually somehow requiring the dispatcher events other solutions above are more appropriate – KVKConsultancy Jan 13 '19 at 22:00
-
1
You can also call the method for the button getting clicked
Button_Click(new object(), new RoutedEventArgs(ButtonBase.ClickEvent));
Anther way is ButtonName.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Both ways need using System.Windows.Controls.Primitives;
Button_Click(new object(), new RoutedEventArgs(ButtonBase.ClickEvent));
ButtonName.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));

- 31
- 2
The problem with the Automation API solution is, that it required a reference to the Framework assembly UIAutomationProvider
as project/package dependency.
An alternative is to emulate the behaviour. In the following there is my extended solution which also condiders the MVVM-pattern with its bound commands - implemented as extension method:
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);
}
}
}

- 715
- 1
- 5
- 16
# Create extension method and use always button #
public static class UIExtension
{
public static void PerformClick(this Button button)
{
button.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
}
}
public partial class MyForm : Window
{
InitializeComponent();
myButton.PerformClick();
}

- 52
- 5