How to programmatically click a button

Back in WinForms it was really easy to simulate a user clicking a Button, you just call a Button’s PerformClick method.  For some reason the WPF Button does not have that method.  It turns out that you need to enter into the automation world to accomplish this task.

Here’s the code:

ButtonAutomationPeer peer =
  new ButtonAutomationPeer( someButton );

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

invokeProv.Invoke();

About these ads

15 Responses to How to programmatically click a button

  1. Andrew Smith says:

    You may want to get the AutomationPeer from the element instead of assuming the type of automation peer to create – i.e. use UIElementAutomationPeer.CreatePeerForElement. Note, despite the name, it will only create it if the element doesn’t already have one created – otherwise it uses the one previously created for the element.

  2. Josh Smith says:

    Andrew,

    Thanks for the tip. I didn’t know about that class. That makes more sense than my approach.

    Josh

  3. Andrew Wood says:

    For arguments sake, in the case of a buttonclick – what’s wrong with using RaiseEvent?

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

    works fine for me.

  4. Josh Smith says:

    Andrew W,

    I suppose that’s another valid way of doing it. :) I’m not sure what differences might exist between using automation and raiseevent. Thanks for the tip!

    Josh

  5. Jordan Nolan says:

    AutomationPeer – that’s just good stuff!

    Of course there is an even simpler and a more complex way to programatically invoke some Button Click functionality.

    The simple way would be to put what you want done in a separate function that is called from the button’s Click event handler and then just call the function when desired.

    The more complex way, but intellectually very satisfying, would be to use a RoutedEvent or RoutedUIEvent.

    For example:

    public partial class Window1 : System.Windows.Window
    {
    public static RoutedCommand ButtonClickCommand = new RoutedCommand();

    public Window1()
    {
    InitializeComponent();

    CommandBinding commandBinding = new CommandBinding( ButtonClickCommand, ButtonClickCommandHandler );
    this.CommandBindings.Add( commandBinding );
    this.button1.Command = ButtonClickCommand;
    }

    private void ButtonClickCommandHandler( object sender, ExecutedRoutedEventArgs e )
    {
    MessageBox.Show( “Button Clicked” );
    }

    private void SomeMethod( )
    {
    ICommand command = this.button1.Command;
    command.Execute( this.button1 );
    }
    }

    The benefit of this is that you have a reusable command divorced from the Button UIElement and can do stuff like handle the command’s CanExecute event to enable and disable the command based upon some condition.

    Thanks for your great blog Josh

  6. Josh Smith says:

    I posted to the WPF Forum asking for opinions on which of the various ways to programmatically click a Button is the best. I got some interesting feedback in favor of using Automation, mostly because it will honor the enabled state of the Button. Here’s the thread: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1329603&SiteID=1

    Josh

  7. Andrew Smith says:

    Actually I think Neil’s point is more that if you had a Command associated with the Button that using RaiseEvent would not cause that command to be executed since the command associated with the button is only executed from the OnClick of the ButtonBase after it has raised the Click event. I think that’s a stronger argument for using the automation method.

  8. Josh Smith says:

    Andrew S,

    Good point. I see what you mean and totally agree. Thanks again!

    Josh

  9. Sal Scozzari says:

    Additionally, the RaiseEvent results in a call to the event handler while still in the calling method. The automation peer method causes the event to be triggered after the invoking method has ended. Just put a breakpoint at the start of the click handler and inspect the call stack to see this. Depending on your circumstances, the automation method may be preferable.

  10. Josh Smith says:

    Sal,

    That’s a very interesting observation. It sounds like using the automation peer can prevent you from needing to do a Dispatcher.BeginInvoke() just to delay the call.

    Nice!

    josh

  11. Randall says:

    Dude… that was a beutiful thing. I really needed that!

  12. George says:

    Great code here… I need to do something like this from a class instead of the WPF form that hosts the button. Is there a way to click a button( or execute a method) on a WPF form from a class?

    Thanks,
    George

  13. Tahnks for posting

  14. chaiguy1337 says:

    Josh, suppose I wanted to spoof a mouse click (or more specifically a mouse down) over a TextBox; how might I go about doing that? I’ve explored both RaiseEvent and UI Automation (the latter just left me baffled), but neither offer an obvious way to do this.

    The reason I need to do this is that I want mouse clicks over a text box to by default go towards dragging a window, and only if the mouse is clicked and released (without moving) should it be passed-on to the TextBox. The problem is that by the time I can determine if it has moved (mouseUp), the initial mouseDown is lost. Is there some way I can recreate it in such a way that it can be sent again, this time with IsHitTestVisible set to true on the text box?

    I already know how to use SendInput, but I was hoping there was a managed solution via WPF.

Follow

Get every new post delivered to your Inbox.

Join 285 other followers

%d bloggers like this: