Respuestas:
WPF adopta un enfoque ligeramente diferente al de WinForms aquí. En lugar de tener la automatización de un objeto integrado en la API, tienen una clase separada para cada objeto que es responsable de automatizarlo. En este caso necesita el ButtonAutomationPeer
para llevar a cabo esta tarea.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
aquí hay una publicación de blog sobre el tema.
Nota: la IInvokeProvider
interfaz se define en el UIAutomationProvider
ensamblaje.
UIAutomationProvider
. Luego tuve que agregarusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
interfaz se define en el UIAutomationProvider
ensamblaje.
Como dijo JaredPar, puede consultar el artículo de Josh Smith sobre Automatización. Sin embargo, si mira los comentarios a su artículo, encontrará una forma más elegante de generar eventos contra los controles de WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Personalmente prefiero el de arriba en lugar de los de automatización.
new RoutedEventArgs(Button.ClickEvent)
no funcionó para mí. Tuve que usar new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. De lo contrario, funciona muy bien!
si desea llamar, haga clic en evento:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
Y si quieres que el botón parezca presionado:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
y sin presionar después de eso:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
o use el ToggleButton
Una forma de "hacer clic" programáticamente en el botón, si tiene acceso a la fuente, es simplemente llamar al controlador de eventos OnClick del botón (o Ejecutar el ICommand asociado con el botón, si está haciendo las cosas de la manera más WPF-y )
¿Por qué estás haciendo esto? ¿Está haciendo algún tipo de prueba automatizada, por ejemplo, o está tratando de realizar la misma acción que realiza el botón desde una sección de código diferente?
Como dijo Greg D , creo que una alternativa a Automation
hacer clic en un botón usando el patrón MVVM (evento de clic generado y comando ejecutado) es llamar al OnClick
método usando la reflexión:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Cuando se usa el patrón de comando MVVM para la función del botón (práctica recomendada), una manera simple de activar el efecto del botón es la siguiente:
someButton.Command.Execute(someButton.CommandParameter);
Esto usará el objeto Command que dispara el botón y pasará el CommandParameter definido por XAML .
El problema con la solución de API de automatización es que requiere una referencia al ensamblaje de Framework UIAutomationProvider
como dependencia de proyecto / paquete.
Una alternativa es emular el comportamiento. A continuación está mi solución extendida que también considera el patrón MVVM con sus comandos vinculados, implementado como método de extensión :
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);
}
}
}