답변:
WPF는 여기서 WinForms와 약간 다른 접근 방식을 취합니다. API에 내장 된 객체를 자동화하는 대신 자동화를 담당하는 각 객체에 대해 별도의 클래스가 있습니다. ButtonAutomationPeer
이 경우이 작업을 수행하기 위해 가 필요합니다 .
ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
여기에 주제에 대한 블로그 게시물입니다.
참고 : IInvokeProvider
인터페이스는 UIAutomationProvider
어셈블리에 정의되어 있습니다.
UIAutomationProvider
. 그런 다음 추가해야했습니다using System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
IInvokeProvider
인터페이스는 UIAutomationProvider
어셈블리에 정의되어 있습니다.
JaredPar가 말했듯이 자동화에 대한 Josh Smith의 기사를 참조 할 수 있다고 말했습니다. 그러나 그의 기사에 대한 의견을 살펴보면 WPF 컨트롤에 대해 이벤트를 발생시키는 더 우아한 방법을 찾을 수 있습니다
someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
나는 개인적으로 자동화 피어 대신 위의 것을 선호합니다.
new RoutedEventArgs(Button.ClickEvent)
하지 않지만 나에게 적합하지 않습니다. 나는을 사용해야했다 new RoutedEventArgs(Primitives.ButtonBase.ClickEvent)
. 그렇지 않으면 훌륭하게 작동합니다!
클릭 이벤트를 호출하려는 경우 :
SomeButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
버튼을 누르는 것처럼 보이는 경우 :
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { true });
그리고 그 후에 누르지 않은 :
typeof(Button).GetMethod("set_IsPressed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(SomeButton, new object[] { false });
또는 ToggleButton을 사용하십시오
소스에 액세스 할 수있는 경우 버튼을 프로그래밍 방식으로 "클릭"하는 한 가지 방법은 버튼의 OnClick 이벤트 핸들러를 호출하거나보다 WPF-y 방식으로 작업을 수행하는 경우 버튼과 관련된 ICommand를 실행하는 것입니다. ).
왜 이런 짓을하는? 예를 들어 일종의 자동 테스트를 수행 중입니까, 아니면 다른 코드 섹션에서 버튼이 수행하는 것과 동일한 작업을 수행하려고합니까?
로 그렉 D가 말했다, 나는 대안을 생각 Automation
부르는하기 위해 MVVM 패턴 (클릭 이벤트가 발생하고 명령이 실행)되어 사용 버튼을 클릭 OnClick
반사를 사용하는 방법 :
typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);
사용하는 경우 MVVM 에 대한 명령 패턴 버튼 기능 (권장 연습), 간단한 방법은 효과 트리거 할 버튼은 다음과 같다 :
someButton.Command.Execute(someButton.CommandParameter);
버튼이 트리거 하는 Command 객체를 사용 하고 XAML에 의해 정의 된 CommandParameter를 전달합니다 .
자동화 API 솔루션의 문제점 UIAutomationProvider
은 프로젝트 / 패키지 종속성으로서 프레임 워크 어셈블리에 대한 참조가 필요하다는 것 입니다.
대안은 행동을 모방하는 것입니다. 다음에는 확장 방법으로 구현 된 바인딩 된 명령으로 MVVM 패턴을 부여하는 확장 솔루션이 있습니다 .
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);
}
}
}