none
Automation vs RaiseEvent RRS feed

  • Question

  • I recently blogged about how to programmatically click a Button in WPF (http://joshsmithonwpf.wordpress.com/2007/03/09/how-to-programmatically-click-a-button).  I used the automation API to click the button:

    ButtonAutomationPeer peer =
      new ButtonAutomationPeer( someButton );

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

    invokeProv.Invoke();

    Someone left a comment mentioning that you can use the RaiseEvent method to achieve the same result:

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

    My question is, which is better?  What's the difference between using these two approaches?  Which does the WPF team at MSFT recommend?

    Thanks for any insights.

    Saturday, March 10, 2007 5:30 PM

Answers

  • I would probably go with the Automation approach as manually raising the event does not properly simulate what happens if the button is clicked with the mouse.
    E.g what if the button binds to a command or is disabled?
    Sunday, March 11, 2007 6:05 PM

All replies

  • I always thought that the difference was that the UI automation approach was for accessing UI elements that aren't inherently part of your app, while the raiseEvent approach can only be used on WPF objects.

    I got the impression that UI automation was introduced to help out with testing in the form of script / batch testing, rather than to be used as the regular method for initiating a programatically initiated event.

    Edit: Just to clarify that raiseEvent can be used on any WPF object rather than just buttons.

    Sunday, March 11, 2007 1:08 AM
  • I would probably go with the Automation approach as manually raising the event does not properly simulate what happens if the button is clicked with the mouse.
    E.g what if the button binds to a command or is disabled?
    Sunday, March 11, 2007 6:05 PM
  • Neil,

    Thanks, that's a good point.

    Josh

    Monday, March 12, 2007 12:41 AM
  • Raising event has a flavor of invoking object's private methods through reflection. Certainly violates contract and potentially makes object's state inconsistent - not to mention that such an invocation could be simply meaningless and/or misleading.


    Monday, March 12, 2007 3:15 PM
  • I have tried using the Automation example provided by Josh, RaiseEvent and also just calling the event handler directly.  In each of these approaches, the button does not "look" clicked on the screen - meaning the mouse over outline and background color do not changed as they do when a user actually clicks it with the mouse.  I want to initiate a button click programmatically and also have the button "look clicked" for the user.  How can I do that?  I really appreciate your help.  Here is some of my code (all of which raises the appropriate event but does not change the appearance of my button).  My button name is btnA. 

     

    Animation example code:

     

    Dim peer As New ButtonAutomationPeer(btnA)

    Dim invokeProv As IInvokeProvider = peer.GetPattern(PatternInterface.Invoke)

    invokeProv.Invoke()

     

    RaiseEvent code:

     

    btnA.RaiseEvent(New System.Windows.RoutedEventArgs(Button.ClickEvent))

     

     

    P.S. I also tried just programmatically setting the button border and background to appear clicked but since there is no window.refresh anymore the window does not repaint to achieve the simulated click.

     

    Any ideas?  Thanks!
    Friday, March 14, 2008 2:40 PM
  • Well you should really not expect that "clicked" behaviour which is due to your mouse hover/down/up and totally depends on the user clicking the button. And the RaiseEvent as well as Automation are just for fraction of second so I am not sure if there may be such behaviour which is quite difficult to observe.

    Another thing you can do is to animate the button when you raise the click event.

    Thanks

    --
    Himanshu
    Friday, March 28, 2008 10:03 AM
  • Thank you, Himanshu.  I thought about using Animation.  I'll try that.  Thanks!

     

    Friday, March 28, 2008 6:01 PM
  • My 2 cents: Automation is a better way because there can be some other logic in between the call and an event raise. Consider simulating the click on the menu item of the context menu. Click will close the menu, raise will not.
    Friday, March 20, 2009 12:44 AM
  • I have a similar problem. When a button is clicked with the mouse, it shows the down image until the action that was initiated by the button has completed. The down image shows the user that the action is not completed yet. I would like to accomplish the same thing when initiating the button click from code. Is there no simple way to do this?
    Thursday, April 2, 2009 12:10 PM
  • I've used this on a RepeatButton, and unfortunately it seems that Automation does not honor the Interval property of the RepeatButton. I have to manually enforce the repeat Interval prior to calling the automation.
    Monday, June 1, 2009 6:57 PM
  • I have almost the same problem with a list box.
    I wanted to invoke the selectedvalue methode but there is only the event.
    this.lstBox.RaiseEvent(new RoutedEventArgs(ListBox.SelectedEvent)) didn't work. The selectedvalue has still the old value.
    I load my date from a database.





              
    Tuesday, July 7, 2009 10:11 PM