Jawaban:
WPF mengambil pendekatan yang sedikit berbeda dari WinForms di sini. Alih-alih memiliki otomatisasi objek yang dibangun ke dalam API, mereka memiliki kelas terpisah untuk setiap objek yang bertanggung jawab untuk mengotomatisasi itu. Dalam hal ini Anda perlu ButtonAutomationPeer
menyelesaikan tugas ini.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Berikut adalah posting blog tentang masalah ini.
Catatan: IInvokeProvider
antarmuka didefinisikan dalam UIAutomationProvider
majelis.
UIAutomationProvider
. Kemudian harus menambahkanusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
antarmuka didefinisikan dalam UIAutomationProvider
majelis.
Seperti yang dikatakan JaredPar, Anda dapat merujuk ke artikel Josh Smith tentang Otomasi. Namun jika Anda melihat melalui komentar di artikelnya, Anda akan menemukan cara yang lebih elegan untuk meningkatkan acara terhadap kontrol WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Saya pribadi lebih suka yang di atas daripada rekan-rekan otomatisasi.
new RoutedEventArgs(Button.ClickEvent)
tidak berhasil untuk saya. Saya harus menggunakan new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. Kalau tidak, bekerja dengan baik!
jika Anda ingin memanggil acara klik:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
Dan jika Anda ingin tombolnya terlihat seperti ditekan:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
dan tidak terbuka setelah itu:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
atau gunakan ToggleButton
Salah satu cara untuk secara programatik "mengklik" tombol, jika Anda memiliki akses ke sumbernya, adalah dengan hanya memanggil pengendali event OnClick tombol (atau Jalankan ICommand yang terkait dengan tombol, jika Anda melakukan hal-hal dengan cara yang lebih WPF-y ).
Mengapa kau melakukan ini? Apakah Anda melakukan semacam pengujian otomatis, misalnya, atau mencoba melakukan tindakan yang sama dengan yang dilakukan tombol dari bagian kode yang berbeda?
Seperti yang dikatakan Greg D , saya berpikir bahwa alternatif untuk Automation
mengklik tombol menggunakan pola MVVM (klik acara yang dibangkitkan dan perintah dieksekusi) adalah memanggil OnClick
metode menggunakan refleksi:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Saat menggunakan pola Perintah MVVM untuk fungsi Tombol (praktik yang disarankan), cara sederhana untuk memicu efek Tombol adalah sebagai berikut:
someButton.Command.Execute(someButton.CommandParameter);
Ini akan menggunakan objek Command yang dipicu tombol dan melewati CommandParameter yang ditentukan oleh XAML .
Masalah dengan solusi API Otomatisasi adalah, bahwa diperlukan referensi ke perakitan Kerangka UIAutomationProvider
sebagai ketergantungan proyek / paket.
Alternatifnya adalah meniru perilaku. Berikut ini adalah solusi saya yang diperluas yang juga menghubungkan pola-MVVM dengan perintah terikat - diimplementasikan sebagai metode ekstensi :
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);
}
}
}