Risposte:
WPF adotta un approccio leggermente diverso rispetto a WinForms qui. Invece di avere l'automazione di un oggetto incorporato nell'API, hanno una classe separata per ogni oggetto responsabile dell'automazione. In questo caso è necessario ButtonAutomationPeer
per eseguire questa attività.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Ecco un post sul blog sull'argomento.
Nota: l' IInvokeProvider
interfaccia è definita UIAutomationProvider
nell'assieme.
UIAutomationProvider
. Quindi ho dovuto aggiungereusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
interfaccia è definita UIAutomationProvider
nell'assieme.
Come ha detto JaredPar, puoi fare riferimento all'articolo di Josh Smith sull'automazione. Tuttavia, se guardi i commenti al suo articolo, troverai un modo più elegante di raccogliere eventi contro i controlli WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Personalmente preferisco quello sopra invece dei peer di automazione.
new RoutedEventArgs(Button.ClickEvent)
non ha funzionato per me. Ho dovuto usare new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. Altrimenti, funziona alla grande!
se vuoi chiamare l'evento click:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
E se vuoi che il pulsante appaia premuto:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
e non compresso dopo quello:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
o utilizzare il ToggleButton
Un modo per "fare clic" programmaticamente sul pulsante, se si ha accesso all'origine, è semplicemente chiamare il gestore eventi OnClick del pulsante (o eseguire l'ICommand associato al pulsante, se si stanno facendo le cose nel modo più WPF-y ).
Perché stai facendo questo? Stai eseguendo una sorta di test automatico, ad esempio, o stai provando a eseguire la stessa azione eseguita dal pulsante da una diversa sezione di codice?
Come ha detto Greg D , penso che un'alternativa a Automation
fare clic su un pulsante usando il modello MVVM (evento click generato e comando eseguito) sia chiamare il OnClick
metodo usando reflection:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Quando si utilizza il modello di comando MVVM per la funzione Pulsante (pratica consigliata), un modo semplice per attivare l'effetto del pulsante è il seguente:
someButton.Command.Execute(someButton.CommandParameter);
Questo utilizzerà l' oggetto Command che viene attivato dal pulsante e passa CommandParameter definito da XAML .
Il problema con la soluzione API di automazione è che richiedeva un riferimento all'assembly Framework UIAutomationProvider
come dipendenza progetto / pacchetto.
Un'alternativa è emulare il comportamento. Di seguito è disponibile la mia soluzione estesa che supporta anche il modello MVVM con i suoi comandi associati, implementato come metodo di estensione :
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);
}
}
}