Câu trả lời:
WPF có một cách tiếp cận hơi khác so với WinForms ở đây. Thay vì tự động hóa một đối tượng được tích hợp trong API, họ có một lớp riêng cho từng đối tượng chịu trách nhiệm tự động hóa nó. Trong trường hợp này, bạn cần phải ButtonAutomationPeer
hoàn thành nhiệm vụ này.
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
Đây là một bài viết trên blog về chủ đề này.
Lưu ý: IInvokeProvider
giao diện được xác định trong UIAutomationProvider
lắp ráp.
UIAutomationProvider
. Sau đó phải thêmusing System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
giao diện được xác định trong UIAutomationProvider
lắp ráp.
Giống như JaredPar cho biết bạn có thể tham khảo bài viết của Josh Smith về Tự động hóa. Tuy nhiên, nếu bạn xem qua các bình luận cho bài viết của anh ấy, bạn sẽ thấy cách nâng cao sự kiện thanh lịch hơn đối với các điều khiển WPF
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
Cá nhân tôi thích cái ở trên thay vì tự động hóa đồng nghiệp.
new RoutedEventArgs(Button.ClickEvent)
không hoạt động với tôi. Tôi đã phải sử dụng new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. Nếu không, làm việc tuyệt vời!
nếu bạn muốn gọi sự kiện bấm vào:
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
Và nếu bạn muốn nút này trông giống như được nhấn:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
và không bị áp bức sau đó:
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
hoặc sử dụng ToggleButton
Một cách để lập trình "bấm" nút, nếu bạn có quyền truy cập vào nguồn, chỉ cần gọi trình xử lý sự kiện OnClick của nút (hoặc Thực thi ICommand được liên kết với nút, nếu bạn đang thực hiện theo cách WPF-y hơn ).
Tại sao anh làm điều này? Bạn đang thực hiện một số loại thử nghiệm tự động, ví dụ, hoặc cố gắng thực hiện cùng một hành động mà nút thực hiện từ một phần khác của mã?
Như Greg D đã nói, tôi nghĩ rằng một cách khác để Automation
nhấp vào nút bằng cách sử dụng mẫu MVVM (nhấp vào sự kiện được nêu và lệnh được thực thi) là gọi OnClick
phương thức bằng phản xạ:
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
Khi sử dụng mẫu Lệnh MVVM cho chức năng Nút (thực hành được khuyến nghị), một cách đơn giản để kích hoạt hiệu ứng của Nút như sau:
someButton.Command.Execute(someButton.CommandParameter);
Điều này sẽ sử dụng đối tượng Command mà nút kích hoạt và vượt qua CommandParameter được xác định bởi XAML .
Vấn đề với giải pháp API tự động hóa là, nó yêu cầu tham chiếu đến khung công tác UIAutomationProvider
dưới dạng phụ thuộc dự án / gói.
Một cách khác là mô phỏng hành vi. Trong phần sau đây có giải pháp mở rộng của tôi, nó cũng điều khiển mẫu MVVM với các lệnh bị ràng buộc của nó - được triển khai như phương thức mở rộng :
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);
}
}
}