Poser une questionPoser une question
 

TraitéeAutomation vs RaiseEvent

  • samedi 10 mars 2007 17:30Josh SmithMVPMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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.

Réponses

  • dimanche 11 mars 2007 18:05Neil Mosafi Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
    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?

Toutes les réponses

  • dimanche 11 mars 2007 01:08Kane- Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.

  • dimanche 11 mars 2007 18:05Neil Mosafi Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
    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?
  • lundi 12 mars 2007 00:41Josh SmithMVPMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    Neil,

    Thanks, that's a good point.

    Josh

  • lundi 12 mars 2007 15:15sfedorov Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.


  • vendredi 14 mars 2008 14:40beckycatania Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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!
  • vendredi 28 mars 2008 10:03Himanshu Arora Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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
  • vendredi 28 mars 2008 18:01beckycatania Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    Thank you, Himanshu.  I thought about using Animation.  I'll try that.  Thanks!

     

  • vendredi 20 mars 2009 00:44Andrey Kozyrev Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.
  • jeudi 2 avril 2009 12:10GSyren Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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?
  • lundi 1 juin 2009 18:57LoopM Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.
  • mardi 7 juillet 2009 22:11JensNewYork Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.