WPF에서 버튼을 프로그래밍 방식으로 클릭하는 방법은 무엇입니까?


144

button.PerformClick()WPF 에는 방법 이 없으므로 프로그래밍 방식으로 WPF 버튼을 클릭하는 방법이 있습니까?

답변:


128

WPF는 여기서 WinForms와 약간 다른 접근 방식을 취합니다. API에 내장 된 객체를 자동화하는 대신 자동화를 담당하는 각 객체에 대해 별도의 클래스가 있습니다. ButtonAutomationPeer이 경우이 작업을 수행하기 위해 가 필요합니다 .

ButtonAutomationPeer peer = new ButtonAutomationPeer(someButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();

여기에 주제에 대한 블로그 게시물입니다.

참고 : IInvokeProvider인터페이스는 UIAutomationProvider어셈블리에 정의되어 있습니다.


2
슬릭, 나는 이것을 몰랐다. 자동화 된 테스트에 매우 유용 할 수 있습니다. 제공된 링크를 사용하여 자동화 피어를 직접 만드는 대신 제공된 팩토리를 사용하도록 제안하는 링크에 대한 의견이 있습니다.
Greg D

7
고마워 에 대한 참조를 추가 할 때까지 내 앱에서 올바른 네임 스페이스를 찾는 데 어려움을 겪었습니다 UIAutomationProvider. 그런 다음 추가해야했습니다using System.Windows.Automation.Peers; using System.Windows.Automation.Provider;
sergeantKK

5
경사를위한 1 개의 강선 :((IInvokeProvider) (new ButtonAutomationPeer(someButton).GetPattern(PatternInterface.Invoke)).Invoke();
Danny Beckett

3
주목할 것은 Invoke 호출이 비동기 적이라는 것입니다. 즉, 단위 테스트에서 사용 중이고 다음 줄이 버튼을 클릭했을 때 예상되는 결과를 확인하는 경우 기다려야 할 수도 있습니다.
denver

3
참고로 IInvokeProvider인터페이스는 UIAutomationProvider어셈블리에 정의되어 있습니다.
Steven Rands

188

JaredPar가 말했듯이 자동화에 대한 Josh Smith의 기사를 참조 할 수 있다고 말했습니다. 그러나 그의 기사에 대한 의견을 살펴보면 WPF 컨트롤에 대해 이벤트를 발생시키는 더 우아한 방법을 찾을 수 있습니다

someButton.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));

나는 개인적으로 자동화 피어 대신 위의 것을 선호합니다.


26
RaiseEvent 솔루션은 이벤트 만 발생시킵니다. Skanaar가 말한 것처럼 버튼과 관련된 명령을 실행하지 않습니다
Eduardo Molteni

4
XAML (예 : <Button Name = "X"Click = "X_Click"/>)을 사용하는 경우 이벤트는 평소와 같이 on click 핸들러에 의해 잡 힙니다. 나에게서 +1!
metao

4
VB를 사용하고 있습니다 ... VB 구절 C #의 코드가 다른지 확실 new RoutedEventArgs(Button.ClickEvent)하지 않지만 나에게 적합하지 않습니다. 나는을 사용해야했다 new RoutedEventArgs(Primitives.ButtonBase.ClickEvent). 그렇지 않으면 훌륭하게 작동합니다!
BrianVPS

3
@EduardoMolteni 및 Skanaar에 대해 자세히 설명하기 위해 이러한 방식으로 Commands에서 제공 한 IsEnabled 기능이 손실되므로 모든 이벤트가 활성화되어 있는지 확인하지 않으면 AutomationPeer가 더 잘 작동합니다.
저스틴 피 호니

34

클릭 이벤트를 호출하려는 경우 :

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을 사용하십시오


22
this.PowerButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));

5

소스에 액세스 할 수있는 경우 버튼을 프로그래밍 방식으로 "클릭"하는 한 가지 방법은 버튼의 OnClick 이벤트 핸들러를 호출하거나보다 WPF-y 방식으로 작업을 수행하는 경우 버튼과 관련된 ICommand를 실행하는 것입니다. ).

왜 이런 짓을하는? 예를 들어 일종의 자동 테스트를 수행 중입니까, 아니면 다른 코드 섹션에서 버튼이 수행하는 것과 동일한 작업을 수행하려고합니까?


그것은 내 문제에 대한 유일한 해결책은 아니지만 나는이 작업을 수행하려고 할 때, 나는, 쉽게 button.PerformClick ()와 같은, 그래서 그냥 조금 호기심이 아니라 발견 ... :)
tghoang

같은 프로젝트에서 다른 창의 메뉴를 클릭해야했고 MyOtherWindow.mnuEntry_Click (Me, New Windows.RoutedEventArgs)이했습니다. 정말 간단합니다.
Andrea Antonangeli 2016 년

4

그렉 D가 말했다, 나는 대안을 생각 Automation부르는하기 위해 MVVM 패턴 (클릭 이벤트가 발생하고 명령이 실행)되어 사용 버튼을 클릭 OnClick반사를 사용하는 방법 :

typeof(System.Windows.Controls.Primitives.ButtonBase).GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(button, new object[0]);

이것은 자식 요소의 이벤트를 사용하여 부모에서 명령을 발생시키는 좋은 방법입니다.
Cool Blue

2

사용하는 경우 MVVM 에 대한 명령 패턴 버튼 기능 (권장 연습), 간단한 방법은 효과 트리거 할 버튼은 다음과 같다 :

someButton.Command.Execute(someButton.CommandParameter);

버튼이 트리거 하는 Command 객체를 사용 하고 XAML에 의해 정의 된 CommandParameter를 전달합니다 .


참고로, 클릭하면 버튼에 미치는 영향 만 트리거합니다 . 메시지 디스패치 큐에서 클릭 이벤트를 생성하지 않습니다. 모든 실질적인 경우에 이것은 불필요한 디스패처 이벤트 (예 : 성능이 더 좋은)를 피하고 피할 것입니다. 그러나 실제로 디스패처 이벤트가 필요한 경우 위의 다른 솔루션이 더 적합합니다.
KVKConsultancy

0

자동화 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);
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.