Réponses:
WPF adopte ici une approche légèrement différente de celle de WinForms. Au lieu d'avoir l'automatisation d'un objet intégrée à l'API, ils ont une classe distincte pour chaque objet qui est responsable de l'automatiser. Dans ce cas, vous avez besoin du ButtonAutomationPeer
pour accomplir cette tâche.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Voici un article de blog sur le sujet.
Remarque: l' IInvokeProvider
interface est définie dans l' UIAutomationProvider
assemblage.
UIAutomationProvider
. Puis a dû ajouterusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
interface est définie dans l' UIAutomationProvider
assemblage.
Comme JaredPar l'a dit, vous pouvez vous référer à l'article de Josh Smith sur l'automatisation. Cependant, si vous regardez à travers les commentaires de son article, vous trouverez un moyen plus élégant de déclencher des événements contre les contrôles WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Personnellement, je préfère celui ci-dessus aux pairs d'automatisation.
new RoutedEventArgs(Button.ClickEvent)
n'a pas fonctionné pour moi. J'ai dû utiliser new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. Sinon, ça marche très bien!
si vous souhaitez appeler l'événement de clic:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
Et si vous voulez que le bouton ait l'air d'avoir été enfoncé:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
et non pressé après cela:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
ou utilisez le bouton ToggleButton
Une façon de "cliquer" par programme sur le bouton, si vous avez accès à la source, consiste simplement à appeler le gestionnaire d'événements OnClick du bouton (ou à exécuter l'ICommand associée au bouton, si vous faites les choses de la manière plus WPF-y ).
Pourquoi fais-tu ça? Faites-vous une sorte de test automatisé, par exemple, ou essayez-vous d'effectuer la même action que le bouton effectue à partir d'une section de code différente?
Comme l'a dit Greg D , je pense qu'une alternative au fait Automation
de cliquer sur un bouton à l'aide du modèle MVVM (événement de clic déclenché et commande exécutée) est d'appeler la OnClick
méthode en utilisant la réflexion:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Lors de l'utilisation du modèle de commande MVVM pour la fonction Button (pratique recommandée), un moyen simple de déclencher l'effet du Button est le suivant:
someButton.Command.Execute(someButton.CommandParameter);
Cela utilisera l' objet Command que le bouton déclenche et transmettra le CommandParameter défini par le XAML .
Le problème avec la solution d'API Automation est qu'elle nécessitait une référence à l'assembly Framework en UIAutomationProvider
tant que dépendance projet / package.
Une alternative consiste à émuler le comportement. Dans ce qui suit, il y a ma solution étendue qui conditionne également le modèle MVVM avec ses commandes liées - implémentées comme méthode d'extension :
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);
}
}
}