Antworten:
WPF verfolgt hier einen etwas anderen Ansatz als WinForms. Anstatt die Automatisierung eines Objekts in die API zu integrieren, haben sie für jedes Objekt, das für die Automatisierung verantwortlich ist, eine separate Klasse. In diesem Fall benötigen Sie die ButtonAutomationPeer
, um diese Aufgabe auszuführen.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Hier ist ein Blog-Beitrag zu diesem Thema.
Hinweis: Die IInvokeProvider
Schnittstelle ist in der UIAutomationProvider
Assembly definiert .
UIAutomationProvider
. Dann musste hinzufügenusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
Schnittstelle in der UIAutomationProvider
Baugruppe definiert .
Wie JaredPar sagte, können Sie sich auf Josh Smiths Artikel zur Automatisierung beziehen. Wenn Sie jedoch die Kommentare zu seinem Artikel durchsehen, werden Sie eine elegantere Möglichkeit finden, Ereignisse gegen WPF-Steuerelemente auszulösen
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Ich persönlich bevorzuge die oben genannte anstelle von Kollegen aus der Automatisierung.
new RoutedEventArgs(Button.ClickEvent)
habe aber bei mir nicht funktioniert. Ich musste benutzen new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. Ansonsten funktioniert super!
Wenn Sie das Klickereignis aufrufen möchten:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
Und wenn Sie möchten, sieht der Knopf so aus, als wäre er gedrückt:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
und danach ungedrückt:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
oder verwenden Sie den ToggleButton
Eine Möglichkeit, programmgesteuert auf die Schaltfläche zu "klicken", wenn Sie Zugriff auf die Quelle haben, besteht darin, einfach den OnClick-Ereignishandler der Schaltfläche aufzurufen (oder den mit der Schaltfläche verknüpften ICommand auszuführen, wenn Sie die Dinge auf WPF-y-Weise ausführen ).
Warum tust du das? Führen Sie beispielsweise eine Art automatisiertes Testen durch oder versuchen Sie, dieselbe Aktion auszuführen, die die Schaltfläche in einem anderen Codeabschnitt ausführt?
Wie Greg D sagte, besteht eine Alternative zum Automation
Klicken auf eine Schaltfläche mithilfe des MVVM-Musters (Klickereignis ausgelöst und Befehl ausgeführt) darin, die OnClick
Methode mithilfe von Reflection aufzurufen :
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Wenn Sie das MVVM- Befehlsmuster für die Schaltflächenfunktion verwenden (empfohlene Vorgehensweise), können Sie den Effekt der Schaltfläche auf einfache Weise wie folgt auslösen :
someButton.Command.Execute(someButton.CommandParameter);
Dies verwendet das Command- Objekt, das die Schaltfläche auslöst, und übergibt den von der XAML definierten CommandParameter .
Das Problem mit der Automation API-Lösung besteht darin, dass ein Verweis auf die Framework-Assembly UIAutomationProvider
als Projekt- / Paketabhängigkeit erforderlich ist.
Eine Alternative besteht darin, das Verhalten zu emulieren. Im Folgenden gibt es meine erweiterte Lösung, die auch das MVVM-Muster mit seinen gebundenen Befehlen bedingt - implementiert als Erweiterungsmethode :
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);
}
}
}