Odpowiedzi:
WPF przyjmuje tutaj nieco inne podejście niż WinForms. Zamiast automatyzacji obiektu wbudowanej w API, mają oddzielną klasę dla każdego obiektu, która jest odpowiedzialna za jego automatyzację. W takim przypadku potrzebujesz ButtonAutomationPeer
do wykonania tego zadania.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Tutaj wpis na blogu na ten temat.
Uwaga: IInvokeProvider
interfejs jest zdefiniowany w UIAutomationProvider
zestawie.
UIAutomationProvider
. Potem trzeba było dodaćusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
interfejs jest zdefiniowany w UIAutomationProvider
zestawie.
Jak powiedział JaredPar, możesz odnieść się do artykułu Josha Smitha na temat automatyzacji. Jeśli jednak przejrzysz komentarze do jego artykułu, znajdziesz bardziej elegancki sposób zgłaszania zdarzeń względem kontrolek WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Osobiście wolę ten powyżej zamiast rówieśników automatyzacji.
new RoutedEventArgs(Button.ClickEvent)
nie działa dla mnie. Musiałem użyć new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. W przeciwnym razie działa świetnie!
jeśli chcesz wywołać zdarzenie kliknięcia:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
A jeśli chcesz, żeby przycisk wyglądał tak, jakby był wciśnięty:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
a potem nieprasowane:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
lub użyj ToggleButton
Jednym ze sposobów programowego „kliknięcia” przycisku, jeśli masz dostęp do źródła, jest po prostu wywołanie procedury obsługi zdarzeń OnClick przycisku (lub wykonanie polecenia ICommand skojarzonego z przyciskiem, jeśli robisz rzeczy w sposób bardziej WPF-y ).
Dlaczego to robisz? Czy na przykład przeprowadzasz jakieś automatyczne testy lub próbujesz wykonać tę samą czynność, którą wykonuje przycisk z innej sekcji kodu?
Jak powiedział Greg D , myślę, że alternatywą dla Automation
kliknięcia przycisku za pomocą wzorca MVVM (wywołanie zdarzenia kliknięcia i wykonanie polecenia) jest wywołanie OnClick
metody za pomocą odbicia:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Podczas korzystania ze wzorca polecenia MVVM dla funkcji przycisku (zalecana praktyka), prosty sposób wywołania efektu przycisku jest następujący:
someButton.Command.Execute(someButton.CommandParameter);
Spowoduje to użycie obiektu Command, który wyzwala przycisk i przekaże CommandParameter zdefiniowany przez XAML .
Problem z rozwiązaniem Automation API polega na tym, że wymagało ono odwołania do zestawu Framework UIAutomationProvider
jako zależności projektu / pakietu.
Alternatywą jest naśladowanie zachowania. Poniżej znajduje się moje rozszerzone rozwiązanie, które również przewodzi wzorzec MVVM z powiązanymi poleceniami - zaimplementowanymi jako metoda rozszerzająca :
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);
}
}
}