Respostas:
O WPF adota uma abordagem ligeiramente diferente da do WinForms aqui. Em vez de ter a automação de um objeto incorporada à API, eles têm uma classe separada para cada objeto responsável por automatizá-lo. Nesse caso, você precisa ButtonAutomationPeer
realizar esta tarefa.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Aqui está um post sobre o assunto.
Nota: a IInvokeProvider
interface é definida na UIAutomationProvider
montagem.
UIAutomationProvider
. Em seguida, tive que adicionarusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
interface é definida na UIAutomationProvider
montagem.
Como JaredPar disse, você pode consultar o artigo de Josh Smith sobre automação. No entanto, se você examinar os comentários de seu artigo, encontrará uma maneira mais elegante de gerar eventos contra os controles do WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Pessoalmente, prefiro o acima, em vez de pares de automação.
new RoutedEventArgs(Button.ClickEvent)
não funcionou para mim. Eu tive que usar new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. Caso contrário, funciona muito bem!
se você quiser chamar o evento click:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
E se você quiser que o botão pareça estar pressionado:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
e não comprimido depois disso:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
ou use o ToggleButton
Uma maneira de "clicar" programaticamente no botão, se você tiver acesso à fonte, é simplesmente chamar o manipulador de eventos OnClick do botão (ou Executar o ICommand associado ao botão, se você estiver fazendo as coisas da maneira mais WPF-y )
Por que você está fazendo isso? Você está realizando algum tipo de teste automatizado, por exemplo, ou tentando executar a mesma ação que o botão executa em uma seção diferente do código?
Como Greg D disse, acho que uma alternativa para Automation
clicar em um botão usando o padrão MVVM (evento de clique gerado e comando executado) é chamar o OnClick
método usando reflexão:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Ao usar o padrão MVVM Command para a função Button (prática recomendada), uma maneira simples de acionar o efeito do Button é a seguinte:
someButton.Command.Execute(someButton.CommandParameter);
Isso usará o objeto Command que o botão dispara e passa o CommandParameter definido pelo XAML .
O problema com a solução da API de automação é que ela requer uma referência ao assembly do Framework UIAutomationProvider
como dependência de projeto / pacote.
Uma alternativa é emular o comportamento. A seguir, há minha solução estendida que também condena o padrão MVVM com seus comandos vinculados - implementados como método de extensão :
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);
}
}
}