사용자 지정 자동화 피어링

Microsoft UI 자동화에 대한 자동화 피어의 개념과 사용자 지정 UI 클래스에 대한 자동화 지원을 제공하는 방법에 대해 설명합니다.

UI 자동화에서는 자동화 클라이언트가 다양한 UI 플랫폼 및 프레임워크의 사용자 인터페이스를 검사하거나 운영하는 데 사용할 수 있는 프레임워크를 제공합니다. Windows 앱을 작성하는 경우 UI에 사용하는 클래스는 이미 UI 자동화 지원을 제공합니다. 봉인되지 않은 기존 클래스에서 파생하여 새로운 종류의 UI 컨트롤 또는 지원 클래스를 정의할 수 있습니다. 이 과정에서, 접근성 지원이 있어야 하지만 기본 UI 자동화 지원에서 다루지 않는 동작을 클래스가 추가할 수 있습니다. 이 경우 기본 구현에서 사용된 AutomationPeer 클래스에서 파생시키고 피어 구현에 필요한 지원을 추가한 다음 새 피어를 만들도록Windows 앱 컨트롤 인프라에 알려 기존 UI 자동화 지원을 확장해야 합니다.

UI 자동화를 사용하여 화면 읽기 프로그램과 같은 접근성 애플리케이션 및 보조 기술뿐만 아니라 품질 보증(테스트) 코드도 사용할 수 있습니다. 어떤 시나리오든, UI 자동화 클라이언트는 사용자 인터페이스 요소를 검사하고 앱 외부의 다른 코드로부터 앱과의 사용자 상호 작용을 시뮬레이션할 수 있습니다. 모든 플랫폼에서의 UI 자동화 및 그에 대한 더 확장된 의미에 대한 자세한 내용은 UI 자동화 개요를 참조하세요.

UI 자동화 프레임워크를 사용하는 고유한 대상이 두 개 있습니다.

  • UI 자동화 클라이언트는 UI 자동화 API를 호출하여 현재 사용자에게 표시되는 모든 UI에 대해 알아봅니다. 예를 들어 화면 읽기 프로그램과 같은 보조 기술은 UI 자동화 클라이언트 역할을 합니다. UI는 관련된 자동화 요소의 트리로 표시됩니다. UI 자동화 클라이언트는 한 번에 하나의 앱 또는 전체 트리만 처리할 수 있습니다. UI 자동화 클라이언트는 UI 자동화 API를 사용하여 트리를 탐색하고 자동화 요소의 정보를 읽거나 변경할 수 있습니다.
  • UI 자동화 공급자는 앱의 일부로 도입한 요소를 UI에 표시하는 API를 구현하여 UI 자동화 트리에 정보를 제공합니다. 새 컨트롤을 만들 때, 이제 UI 자동화 공급자 시나리오에서 참가자 역할을 해야 합니다. 공급자로서, 모든 UI 자동화 클라이언트가 UI 자동화 프레임워크를 사용하여 접근성 및 테스트 목적으로 컨트롤과 상호 작용할 수 있는지 확인해야 합니다.

통상 UI 자동화 프레임워크에는 UI 자동화 클라이언트용 API와 UI 자동화 공급자용 API라는 비슷한 이름의 API까지해서 병렬 API가 있습니다. 대부분의 경우, 이 항목에서 다루는 API는 UI 자동화 공급자에 대한 API이며, 특히 해당 UI 프레임워크에서 공급자 확장성을 가능하게 하는 클래스 및 인터페이스에 대한 것입니다. 경우에 따라 UI 자동화 클라이언트에서 사용하는 UI 자동화 API를 언급하여 몇 가지 관점을 제공하거나 클라이언트와 공급자 API의 상관 관계를 지정하는 조회 테이블을 제공합니다. 클라이언트 관점에 대한 자세한 내용은 UI 자동화 클라이언트 프로그래머 가이드를 참조하세요.

참고 항목

UI 자동화 클라이언트는 통상 관리 코드를 사용하지 않으며 UWP 앱으로 구현되지 않습니다(통상 데스크톱용 앱입니다). UI 자동화는 특정 구현이나 프레임워크가 아닌 표준을 기반으로 합니다. 화면 읽기 프로그램과 같은 보조 기술 제품을 비롯한 많은 기존 UI 자동화 클라이언트는 COM(구성 요소 객체 모델) 인터페이스를 사용하여 자식 창에서 실행되는 UI 자동화, 시스템 및 앱과 상호 작용합니다. COM 인터페이스 및 COM을 사용하여 UI 자동화 클라이언트를 작성하는 방법에 대한 자세한 내용은 UI 자동화 기본 사항을 참조하세요.

사용자 지정 UI 클래스에 대한 UI 자동화 지원의 기존 상태 확인

사용자 지정 컨트롤에 대한 자동화 피어를 구현하기 전에, 기본 클래스와 해당 자동화 피어가 필요한 접근성 또는 자동화 지원을 이미 제공하고 있는지 테스트해야 합니다. 많은 경우, FrameworkElementAutomationPeer 구현, 특정 피어 및 구현하는 패턴의 조합을 통해 기본적이지만 만족스러운 접근성 경험을 제공합니다. 사실 여부는 컨트롤에 대한 객체 모델 노출과 기본 클래스에 대한 변경 내용 개수에 따라 달라집니다. 또한 기본 클래스 기능에 대한 추가가 템플릿 계약의 새 UI 요소 또는 컨트롤의 시각적 모양과 관련이 있는지 여부에 따라 달라집니다. 경우에 따라 변경 내용으로 인해 추가 접근성 지원이 필요한 새로운 측면에서의 사용자 경험이 도입될 수 있습니다.

기존 기본 피어 클래스를 사용하여 기본 접근성 지원을 제공하는 경우에도 자동화된 테스트 시나리오에 대해 UI 자동화 정확한 ClassName 정보를 보고할 수 있도록 피어를 정의하는 것이 가장 좋습니다. 이 고려 사항은 제3자 사용을 목적으로 한 컨트롤을 작성하는 경우에 특히 중요합니다.

자동화 피어 클래스

UWP는 Windows Forms, WPF(Windows Presentation Foundation) 및 Microsoft Silverlight와 같은 이전 관리 코드 UI 프레임워크에서 사용하는 기존 UI 자동화 기술 및 규칙을 기반으로 합니다. 대부분의 컨트롤 클래스와 해당 함수 및 용도는 이전 UI 프레임워크의 원본이기도 합니다.

규칙에 따라 피어 클래스 이름은 컨트롤 클래스 이름으로 시작하고 "AutomationPeer"로 끝납니다. 예를 들어, ButtonAutomationPeerButton 컨트롤 클래스를 위한 피어 클래스입니다.

참고 항목

이 항목에서는, 컨트롤 피어를 구현할 때 접근성과 관련된 속성이 더 중요하다고 간주합니다. 그러나 UI 자동화 지원에 대한 보다 일반적인 개념을 위해서는 UI 자동화 공급자 프로그래머 가이드UI 자동화 기본 사항에 설명된 대로 권장 사항에 따라 피어를 구현해야 합니다. 이러한 항목에서는 UWP 프레임워크에서 UI 자동화 정보를 제공하는 데 사용하는 특정 AutomationPeer API를 다루지 않지만 클래스를 식별하거나 다른 정보 또는 상호 작용을 제공하는 속성을 설명합니다.

피어, 패턴 및 컨트롤 형식

컨트롤 기능의 특정 측면을 UI 자동화 클라이언트에 노출하는 인터페이스 구현을 컨트롤 패턴 이라고 합니다. UI 자동화 클라이언트는 컨트롤 패턴을 통해 노출되는 속성과 메서드를 사용하여 컨트롤의 기능에 대한 정보를 검색하거나 런타임에 컨트롤의 동작을 조작합니다.

컨트롤 패턴은 컨트롤 형식 및 컨트롤의 모양에 관계없이 컨트롤의 기능을 분류하고 노출하는 방법을 제공합니다. 예를 들어, 테이블 형식 인터페이스를 제공하는 컨트롤은 Grid 컨트롤 패턴을 사용하여 테이블의 행과 열 수를 표시하고 UI 자동화 클라이언트가 테이블에서 항목을 검색할 수 있도록 합니다. 예를 들어, 버튼처럼 호출할 수 있는 컨트롤에 대해 Invoke 컨트롤 패턴을 사용하고, 목록 상자나 리스트 뷰, 콤보 상자처럼 스크롤바가 있는 컨트롤에 대해서는 Scroll 컨트롤 패턴을 사용합니다. 각 컨트롤 패턴은 별도 기능을 나타내며, 컨트롤 패턴을 조합하여 특정 컨트롤에서 지원하는 기능의 전체 세트를 설명할 수 있습니다.

인터페이스가 COM 객체와 관련되는 것과 같이, 컨트롤 패턴은 UI 객체와 관련이 있습니다. COM에서, 객체를 쿼리하여 객체가 지원하는 인터페이스를 확인하고 이러한 인터페이스를 사용하여 기능에 액세스할 수 있습니다. UI 자동화에서, UI 자동화 클라이언트는 UI 자동화 요소를 쿼리하여 UI 자동화 클라이언트가 지원하는 컨트롤 패턴을 확인한 다음, 요소와 상호 작용할 수 있으며 지원되는 컨트롤 패턴에 의해 노출되는 속성, 메서드, 이벤트 및 구조를 통해 피어링된 컨트롤과 상호 작용합니다.

자동화 피어의 기본 목적 중 하나는 UI 요소가 피어를 통해 지원할 수 있는 패턴을 제어하는 UI 자동화 클라이언트에 보고하는 것입니다. 이를 위해 UI 자동화 공급자가 GetPattern 메서드 동작을 변경하는 새 피어를 구현하려면 GetPatternCore 메서드를 재정의해야 합니다. UI 자동화 클라이언트는 UI 자동화 공급자가 GetPattern호출에 매핑하는 호출을 수행합니다. UI 자동화 클라이언트는 상호 작용하려는 각 특정 패턴을 쿼리합니다. 피어가 패턴을 지원하는 경우, 그 자체에 대한 객체 참조를 반환합니다. 그렇지 않으면 null을 반환합니다. 반환이 null이 아닌 경우, UI 자동화 클라이언트는 해당 컨트롤 패턴과 상호 작용하기 위해 패턴 인터페이스의 API를 클라이언트로 호출할 수 있다고 예상합니다.

피어가 나타내는 컨트롤의 기능을 광범위하게 정의하는 방법을 컨트롤 형식 이라고 합니다. 패턴이 가져올 수 있는 정보 또는 특정 인터페이스를 통해 수행할 수 있는 작업을 UI 자동화 알려주지만 컨트롤 형식은 그 위로 한 수준 더 높은 곳에 존재하기 때문에 컨트롤 패턴과는 다른 개념입니다. 각 컨트롤 형식에는 UI 자동화 이러한 측면에 대한 지침이 있습니다.

  • UI 자동화 컨트롤 패턴: 컨트롤 형식은 각기 다르게 분류된 정보 또는 상호 작용을 나타내는 둘 이상의 패턴을 지원할 수 있습니다. 각 컨트롤 형식에는 컨트롤이 지원해야 하는 컨트롤 패턴 세트, 선택 사항인 세트 및 컨트롤이 지원하지 않아야 하는 세트가 있습니다.
  • UI 자동화 속성 값: 각 컨트롤 형식에는 컨트롤이 지원해야 하는 속성 세트가 있습니다. 이러한 속성은 패턴별 속성이 아니라 UI 자동화 속성 개요에 설명된 대로 일반 속성입니다.
  • UI 자동화 이벤트: 각 컨트롤 형식에는 컨트롤이 지원해야 하는 이벤트 세트가 있습니다. 다시 언급하지만 UI 자동화 이벤트 개요에 설명된 대로 패턴별 이벤트가 아니라 일반 이벤트입니다.
  • UI 자동화 트리 구조: 각 컨트롤 형식은 컨트롤이 UI 자동화 트리 구조에 표시되는 방법을 정의합니다.

프레임워크에 대한 자동화 피어를 구현하는 방법과 관계없이, UI 자동화 클라이언트 기능은 UWP에 연결되지 않으며, 보조 기술 같은 기존 UI 자동화 클라이언트는 COM과 같은 다른 프로그래밍 모델을 사용할 가능성이 실제로 높습니다. COM에서, 클라이언트는 클라이언트는 요청된 패턴 또는 속성, 이벤트 또는 트리 검사에 대한 일반 UI 자동화 프레임워크를 구현하는 COM 컨트롤 패턴 인터페이스에 QueryInterface 를 사용할 수 있습니다. 패턴의 경우, UI 자동화 프레임워크를 통해 해당 인터페이스 코드를 앱의 UI 자동화 공급자 및 관련 피어에 대해 실행되는 UWP 코드로 마샬링합니다.

C# 또는 Microsoft Visual Basic으로 작성된 UWP 앱 등 관리 코드 프레임워크에 대한 컨트롤 패턴을 구현하는 경우 COM 인터페이스 표현을 사용하는 대신 .NET Framework 인터페이스를 사용하여 이러한 패턴을 나타낼 수 있습니다. 예를 들어, Invoke 패턴의 Microsoft .NET 공급자 구현에 대한 UI 자동화 패턴 인터페이스는 IInvokeProvider입니다.

컨트롤 패턴, 공급자 인터페이스 및 해당 용도 목록은, 컨트롤 패턴 및 인터페이스를 참조하세요. 컨트롤 형식 목록의 경우, UI 자동화 컨트롤 형식 개요를 참조하세요.

컨트롤 패턴을 구현하는 방법에 대한 지침

컨트롤 패턴 및 컨트롤 패턴의 용도는 UI 자동화 프레임워크의 광범위한 정의에 포함되며 UWP 앱에 대한 접근성 지원에만 적용되지는 않습니다. 컨트롤 패턴을 구현할 때는 이 문서 및 UI 자동화 사양에서 설명하는 지침과 일치하는 방식으로 구현해야 합니다. 지침을 찾고 있다면 일반적으로 Microsoft 설명서를 사용할 수 있으며 사양을 참조할 필요가 없습니다. 각 패턴에 대한 지침이 설명하는 바는 다음과 같습니다: UI 자동화 컨트롤 패턴 구현. 이 영역의 각 항목에는 "구현 지침 및 규칙" 섹션과 "필수 멤버" 섹션이 있습니다. 이 지침은 일반적으로 공급자용 컨트롤 패턴 인터페이스 참조에서 관련 컨트롤 패턴 인터페이스의 특정 API를 참조합니다. 이러한 인터페이스는 네이티브/COM 인터페이스이며 해당 API는 COM 스타일 구문을 사용합니다. 그러나 표시되는 모든 항목은 Windows.UI.Xaml.Automation.Provider 네임스페이스에 동일한 것을 갖고 있습니다.

기본 자동화 피어를 사용하고 해당 동작을 확장하는 경우, 해당 피어는 이미 UI 자동화 지침에 따라 작성되었습니다. 컨트롤 패턴을 지원하는 경우, UI 자동화 컨트롤 패턴 구현에 대한 지침에 따라 해당 패턴 지원을 사용할 수 있습니다. 컨트롤 피어가 UI 자동화에 의해 정의된 컨트롤 형식을 대표한다고 보고하는 경우, UI 자동화 컨트롤 형식 지원 에 설명된 지침 뒤에 해당 피어가 있습니다.

그럼에도 불구하고 피어 구현의 UI 자동화 권장 사항을 따르기 위해 컨트롤 패턴 또는 컨트롤 형식에 대한 추가 지침이 필요할 수 있습니다. UWP 컨트롤에 아직 기본 구현으로 존재하지 않는 패턴 또는 컨트롤 형식 지원을 구현하는 경우 특히 그렇습니다. 예를 들어 주석 패턴은 기본 XAML 컨트롤에서 구현되지 않습니다. 그러나 주석을 광범위하게 사용하는 앱이 있을 수 있으므로 해당 기능에 액세스할 수 있도록 표시하려고 합니다. 이 시나리오의 경우, 피어가 IAnnotationProvider 를 구현해야 하며 문서가 주석을 지원함을 나타내기 위해 적절한 속성을 가진 Document 컨트롤 형식을 보고해야 합니다.

방향 및 일반 지침으로 UI 자동화 컨트롤 패턴 구현 또는 UI 자동화 컨트롤 형식 지원 하의 패턴을 참조하는 지침을 사용하는 것이 좋습니다. API의 목적에 대한 설명 및 설명에 대한 API 링크 중 일부를 따르려고 할 수도 있습니다. 그러나 UWP 앱 프로그래밍에 필요한 구문 관련 항목의 경우 Windows.UI.Xaml.Automation.Provider 네임스페이스 내에서 해당하는 API를 찾고, 자세한 내용을 보려면 해당 참조 페이지를 사용합니다.

빌트인 자동화 피어 클래스

일반적으로, 요소는 사용자의 UI 활동을 수락하거나 앱의 대화형 또는 의미 있는 UI를 나타내는 보조 기술 사용자가 필요로 하는 정보를 포함하는 경우 자동화 피어 클래스를 구현합니다. 일부 UWP 시각적 요소에는 자동화 피어가 없습니다. 자동화 피어를 구현하는 클래스의 예로는 ButtonTextBox입니다. 자동화 피어를 구현하지 않는 클래스의 예로는 BorderPanel기반의 클래스로 예를 들어 GridCanvas가 있습니다. 시각적 객체만 잇는 레이아웃 동작을 제공하기 때문에 패널 에는 피어가 없습니다. 사용자가 패널과 상호 작용하는 접근성과 연관된 방법은 없습니다. 자식 요소는 피어 또는 요소 표현이 있는 트리에서 사용 가능한 다음 부모의 자식 요소로 UI 자동화 트리에 패널 에 포함된 자식 요소는 무엇이든 보고됩니다.

UI 자동화 및 UWP 프로세스 경계

일반적으로 UWP 앱에 액세스하는 UI 자동화 클라이언트 코드는 out-of-process로 실행됩니다. UI 자동화 프레임워크 인프라를 사용하면 정보가 프로세스 경계를 넘을 수 있습니다. 이 개념은 UI 자동화 기본 사항에서 자세히 설명되어 있습니다.

OnCreateAutomationPeer

모든 클래스는 UIElement 파생되었고 보호받는 가상 메서드 OnCreateAutomationPeer를 포함합니다. 자동화 피어에 대한 객체 초기화 시퀀스는 OnCreateAutomationPeer 를 호출하여 각 컨트롤에 대한 자동화 피어 객체를 가져오므로 런타임 사용을 위한 UI 자동화 트리를 생성합니다. UI 자동화 코드는 피어를 사용하여 컨트롤의 특성 및 기능에 대한 정보를 가져오고 컨트롤 패턴을 사용해 대화형 사용을 시뮬레이션할 수 있습니다. 자동화를 지원하는 사용자 지정 컨트롤은 OnCreateAutomationPeer 을 재정의하고 AutomationPeer에서 파생된 클래스의 인스턴스를 반환해야 합니다. 예를 들어, ButtonBase 클래스에서 사용자 지정 컨트롤이 파생된 경우, OnCreateAutomationPeer 에서 반환된 객체는 ButtonBaseAutomationPeer에서 파생되어야 합니다.

사용자 지정 컨트롤 클래스를 작성하고 새 자동화 피어도 제공하려는 경우, 피어의 새 인스턴스를 반환하도록 사용자 지정 컨트롤에 대한 OnCreateAutomationPeer 메서드를 재정의해야 합니다. 피어 클래스는 AutomationPeer에서 직접 또는 간접적으로 파생되어야 합니다.

예를 들어, 다음 코드는 사용자 지정 컨트롤 NumericUpDown 이 UI 자동화 목적으로 피어를 NumericUpDownPeer 사용해야 한다고 선언합니다.

using Windows.UI.Xaml.Automation.Peers;
...
public class NumericUpDown : RangeBase {
    public NumericUpDown() {
    // other initialization; DefaultStyleKey etc.
    }
    ...
    protected override AutomationPeer OnCreateAutomationPeer()
    {
        return new NumericUpDownAutomationPeer(this);
    }
}
Public Class NumericUpDown
    Inherits RangeBase
    ' other initialization; DefaultStyleKey etc.
       Public Sub New()
       End Sub
       Protected Overrides Function OnCreateAutomationPeer() As AutomationPeer
              Return New NumericUpDownAutomationPeer(Me)
       End Function
End Class
// NumericUpDown.idl
namespace MyNamespace
{
    runtimeclass NumericUpDown : Windows.UI.Xaml.Controls.Primitives.RangeBase
    {
        NumericUpDown();
        Int32 MyProperty;
    }
}

// NumericUpDown.h
...
struct NumericUpDown : NumericUpDownT<NumericUpDown>
{
	...
    Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer()
    {
        return winrt::make<MyNamespace::implementation::NumericUpDownAutomationPeer>(*this);
    }
};
//.h
public ref class NumericUpDown sealed : Windows::UI::Xaml::Controls::Primitives::RangeBase
{
// other initialization not shown
protected:
    virtual AutomationPeer^ OnCreateAutomationPeer() override
    {
         return ref new NumericUpDownAutomationPeer(this);
    }
};

참고 항목

사용자 지정 자동화 피어의 새 인스턴스를 초기화하고 호출 컨트롤을 소유자로 전달하고 해당 인스턴스를 반환하는 것 외에는 OnCreateAutomationPeer 구현이 아무 작업도 수행하지 않아야 합니다. 이 메서드에서 추가 논리를 시도하지 마세요. 특히 동일한 호출 내에서 AutomationPeer 가 소멸될 수 있는 논리는 예기치 않은 런타임 동작을 초래할 수 있습니다.

일반적인 OnCreateAutomationPeer의 구현에서는, 메서드 재정의가 컨트롤 클래스 정의 나머지 부분과 동일한 범위에 있으므로 소유자this 또는 Me 라고 지정됩니다.

실제 피어 클래스 정의는 컨트롤과 동일한 코드 파일 또는 별도의 코드 파일에서 수행할 수 있습니다. 피어 정의는 모두 피어를 제공하는 컨트롤과 별도의 네임스페이스인 Windows.UI.Xaml.Automation.Peers 네임스페이스에 있습니다. 피어를 별도의 네임스페이스에서 선언하도록 선언할 수 있습니다. 단, OnCreateAutomationPeer 메서드 호출에 필요한 메서드를 참조하는 경우 한정입니다.

올바른 피어 기본 클래스 선택

파생시킨 컨트롤의 기존 피어 논리와 가장 일치하는 기본 클래스에서 AutomationPeer 가 파생되었는지 확인합니다. 이전 예제의 경우, NumericUpDownRangeBase에서 파생되기 때문에, 피어를 RangeBaseAutomationPeer 기반으로 하는 클래스를 사용할 수 있습니다. 컨트롤 자체를 파생하는 방법과 병렬로 가장 일치하는 피어 클래스를 사용하면 기본 피어 클래스가 이미 구현하므로 IRangeValueProvider 기능 중 적어도 일부는 재정의되지 않도록 방지할 수 있습니다.

기본 Control 클래스에는 해당 피어 클래스가 없습니다. 필요한 피어 클래스가 Control에서 파생된 사용자 지정 컨트롤에 해당해야 하는 경우, 사용자 지정 피어 클래스를 FrameworkElementAutomationPeer에서 파생시켜야 합니다.

만약 ContentControl 에서 직접 파생시키는 경우, 피어 클래스를 참조하는 OnCreateAutomationPeer 구현이 없기 때문에 해당 클래스에는 기본 자동화 피어 동작이 없습니다. 따라서 자체 피어를 사용하도록 OnCreateAutomationPeer 를 구현하거나, 해당 수준의 접근성 지원이 컨트롤에 적합한 경우 FrameworkElementAutomationPeer 를 피어로 사용해야 합니다.

참고 항목

일반적으로 AutomationPeer 에서 파생시키기 보다는 FrameworkElementAutomationPeer에서 파생시킵니다. 만약 AutomationPeer 에서 직접 파생된 경우, FrameworkElementAutomationPeer에서 제공되는 많은 기본 접근성 지원을 복제해야 합니다.

사용자 지정 피어 클래스 초기화

자동화 피어는 기본 초기화를 위해 소유자 컨트롤의 인스턴스를 사용하는 형식 안전 생성자를 정의해야 합니다. 다음 예제에서는, 구현이 소유자 값을 RangeBaseAutomationPeer 베이스에 전달하며, 궁극적으로는 FrameworkElementAutomationPeer소유자FrameworkElementAutomationPeer.Owner로 설정합니다.

public NumericUpDownAutomationPeer(NumericUpDown owner): base(owner)
{}
Public Sub New(owner As NumericUpDown)
    MyBase.New(owner)
End Sub
// NumericUpDownAutomationPeer.idl
import "NumericUpDown.idl";
namespace MyNamespace
{
    runtimeclass NumericUpDownAutomationPeer : Windows.UI.Xaml.Automation.Peers.AutomationPeer
    {
        NumericUpDownAutomationPeer(NumericUpDown owner);
        Int32 MyProperty;
    }
}

// NumericUpDownAutomationPeer.h
...
struct NumericUpDownAutomationPeer : NumericUpDownAutomationPeerT<NumericUpDownAutomationPeer>
{
    ...
    NumericUpDownAutomationPeer(MyNamespace::NumericUpDown const& owner);
};
//.h
public ref class NumericUpDownAutomationPeer sealed :  Windows::UI::Xaml::Automation::Peers::RangeBaseAutomationPeer
//.cpp
public:    NumericUpDownAutomationPeer(NumericUpDown^ owner);

AutomationPeer의 핵심 메서드

UWP 인프라를 위해, 재정의 가능한 자동화 피어의 메서드는 UI 자동화 공급자가 UI 자동화 클라이언트의 전달 지점으로 사용하는 공용 액세스 메서드 및 UWP 클래스가 동작에 영향을 미치기 위해 재정의할 수 있는 보호된 "Core" 사용자 지정 메서드의 한 쌍의 일부입니다. 메서드 쌍은 기본적으로 함께 연결되므로 액세스 메서드에 대한 호출은 항상 공급자 구현이 있는 병렬 "Core" 메서드를 호출하거나 대체(fallback)로 기본 클래스에서 기본 구현을 호출합니다.

사용자 지정 컨트롤에 대한 피어를 구현할 때, 사용자 지정 컨트롤과 관련된 고유한 동작을 노출하고자 하는 기본 자동화 피어 클래스로부터 모든 "Core" 메서드를 재정의해야 합니다. UI 자동화 코드는 피어 클래스의 public 메서드를 호출하여 컨트롤에 대한 정보를 가져옵니다. 컨트롤에 대한 정보를 제공하려면 컨트롤 구현 및 디자인이 기본 자동화 피어 클래스에서 지원하는 것과 다른 접근성 시나리오 또는 기타 UI 자동화 시나리오를 만들 때 "Core"로 끝나는 이름으로 각 메서드를 재정의합니다.

최소한 새 피어 클래스를 정의할 때마다 다음 예제와 같이 GetClassNameCore 메서드를 구현합니다.

protected override string GetClassNameCore()
{
    return "NumericUpDown";
}

참고 항목

문자열을 메서드 본문에 직접 저장하지 않고 상수로 저장할 수도 있지만 이는 사용자에게 달려 있습니다. 이 GetClassNameCore의 경우, 문자열을 지역화할 필요가 없습니다. 이 LocalizedControlType 속성은 ClassName이 아닌 UI 자동화 클라이언트에서 지역화된 문자열이 필요할 때마다 사용됩니다.

GetAutomationControlType

일부 보조 기술은 UI 자동화 트리에 있는 항목의 특성을 보고할 때 GetAutomationControlType 값을 Name 이외의 추가 정보로 직접 사용합니다. 컨트롤이 파생되는 컨트롤과 크게 다르고 컨트롤에서 사용하는 기본 피어 클래스에서 보고하는 것과 다른 컨트롤 형식을 보고하려는 경우, 피어를 구현하고 피어 구현에서 GetAutomationControlTypeCore 를 재정의해야 합니다. 이는 기본 피어가 컨트롤 형식에 대한 정확한 정보를 제공하지 않는 ItemsControl 또는 ContentControl과 같은 일반화된 기본 클래스에서 파생되는 경우에 특히 중요합니다.

구현된 GetAutomationControlTypeCore 에서 AutomationControlType 값을 반환하여 컨트롤을 설명합니다. 비록 AutomationControlType.Custom을 반환할 수는 있지만, 컨트롤의 기본 시나리오를 정확하게 설명하는 경우에는 더 구체적인 컨트롤 형식 중 하나를 반환해야 합니다. 다음은 예입니다.

protected override AutomationControlType GetAutomationControlTypeCore()
{
    return AutomationControlType.Spinner;
}

참고 항목

만약 AutomationControlType.Custom을 지정하는 것이 아니라면, GetLocalizedControlTypeCore 를 구현하여 LocalizedControlType 속성 값을 클라이언트에 제공할 필요가 없습니다. UI 자동화 공통 인프라가 번역을 제공하는 값은 AutomationControlType 으로 AutomationControlType.Custom이 아닙니다.

GetPattern 및 GetPatternCore

피어의 GetPatternCore 구현은 입력 매개 수에 요청된 패턴을 지원하는 객체를 반환합니다. 특히, UI 자동화 클라이언트는 GetPattern 메서드로 전달되는 메서드를 호출하고, 요청된 패턴의 이름을 지정하는 PatternInterface 열거형 값을 지정합니다. 지정된 패턴을 구현하는 객체를 GetPatternCore 재정의에서 반환해야 합니다. 피어가 패턴을 지원한다고 보고할 때마다 해당 패턴 인터페이스를 구현해야 하므로, 해당 객체가 피어 그 자체입니다. 피어에 패턴의 사용자 지정 구현이 없지만 피어의 기본이 패턴을 구현한다는 것을 알고 있는 경우, 호출할 수 있는 기본 형식의 GetPatternCore 구현은 GetPatternCore에 있습니다. 피어에서 패턴을 지원하지 않는 경우, 피어의 GetPatternCorenull 을 반환해야 합니다. 그러나 구현에서 직접 null 을 반환하는 대신, 일반적으로 기본 구현에 대한 호출을 사용하여 지원되지 않는 패턴에 대해 null 을 반환합니다.

패턴이 지원되면, GetPatternCore 구현은 can return this 또는 Me를 반환할 수 있습니다. UI 자동화 클라이언트는 GetPattern 반환 값을 null값이 아닐 때마다 요청된 인터페이스로 캐스팅합니다.

피어 클래스가 다른 피어에서 상속되고 필요한 모든 지원 및 패턴 보고가 기본 클래스에서 이미 처리된 경우 GetPatternCore 를 구현할 필요가 없습니다. 예를 들어 RangeBase에서 파생되는 범위 컨트롤을 구현하고 피어가 RangeBaseAutomationPeer에서 파생되는 경우, 해당 피어는 PatternInterface.RangeValue 에 대해 자신을 반환하고 패턴을 지원하는 IRangeValueProvider 인터페이스의 작업을 구현을 갖습니다.

리터럴 코드는 아니지만, 이 예제에서는 근사화하는 GetPatternCore 는 이미 RangeBaseAutomationPeer에 있습니다.

protected override object GetPatternCore(PatternInterface patternInterface)
{
    if (patternInterface == PatternInterface.RangeValue)
    {
        return this;
    }
    return base.GetPattern(patternInterface);
}

기본 피어 클래스에서 필요한 모든 지원이 없는 피어를 구현하거나 피어에서 지원할 수 있는 기본 상속 패턴 세트를 변경하거나 추가하려는 경우 GetPatternCore 를 재정의하여 UI 자동화 클라이언트가 패턴을 사용할 수 있도록 해야 합니다.

UI 자동화 지원의 UWP 구현에서 사용할 수 있는 공급자 패턴 목록은 Windows.UI.Xaml.Automation.Provider를 참조하세요. 이러한 각 패턴에는 PatternInterface 열거형의 값이 있는데, 이는 UI 자동화 클라이언트가 GetPattern 호출에서 패턴을 요청하는 방법입니다.

피어는 둘 이상의 패턴을 지원한다고 보고할 수 있습니다. 이 경우, 재정의는 지원되는 각 PatternInterface 값에 대한 반환 경로 논리를 포함하고 일치하는 각 사례에서 피어를 반환해야 합니다. 호출자는 한 번에 하나의 인터페이스만 요청하며, 호출자가 예상된 인터페이스로 캐스팅하는 것은 호출자에게 달려 있습니다.

다음은 사용자 지정 피어에 대한 GetPatternCore 재정의의 예입니다. 두 가지 패턴, IRangeValueProviderIToggleProvider에 대한 지원을 보고합니다. 여기서 컨트롤은 전체 화면(토글 모드)으로 표시할 수 있고 사용자가 위치(범위 컨트롤)를 선택할 수 있는 진행률 표시줄이 있는 미디어 디스플레이 컨트롤입니다. 이 코드는 XAML 접근성 샘플에서 제공되었습니다.

protected override object GetPatternCore(PatternInterface patternInterface)
{
    if (patternInterface == PatternInterface.RangeValue)
    {
        return this;
    }
    else if (patternInterface == PatternInterface.Toggle)
    {
        return this;
    }
    return null;
}

하위 요소에서 패턴 전달

또한 GetPatternCore 메서드 구현은 하위 요소 또는 파트를 호스트에 대한 패턴 공급자로 지정할 수 있습니다. 이 예제에서는 ItemsControl 이 스크롤 패턴 처리를 내부 ScrollViewer 컨트롤의 피어로 전송하는 방법을 모방합니다. 패턴 처리를 위한 하위 요소를 지정하기 위해, 이 코드는 하위 요소 개체를 가져오고 FrameworkElementAutomationPeer.CreatePeerForElement 메서드를 사용하여 피어를 만들며 새 피어를 반환합니다.

protected override object GetPatternCore(PatternInterface patternInterface)
{
    if (patternInterface == PatternInterface.Scroll)
    {
        ItemsControl owner = (ItemsControl) base.Owner;
        UIElement itemsHost = owner.ItemsHost;
        ScrollViewer element = null;
        while (itemsHost != owner)
        {
            itemsHost = VisualTreeHelper.GetParent(itemsHost) as UIElement;
            element = itemsHost as ScrollViewer;
            if (element != null)
            {
                break;
            }
        }
        if (element != null)
        {
            AutomationPeer peer = FrameworkElementAutomationPeer.CreatePeerForElement(element);
            if ((peer != null) && (peer is IScrollProvider))
            {
                return (IScrollProvider) peer;
            }
        }
    }
    return base.GetPatternCore(patternInterface);
}

기타 핵심 메서드

컨트롤은 기본 시나리오에 해당하는 키보드를 지원해야 할 수 있습니다. 필요한 이유에 대한 자세한 내용은 키보드 접근성을 참조하세요. 키 지원을 구현하는 것은 컨트롤의 논리에 속하기 때문에 피어 코드가 아니라 반드시 컨트롤 코드의 일부여야 하지만, 사용되는 키를 UI 자동화 클라이언트에 보고하도록 GetAcceleratorKeyCoreGetAccessKeyCore 메서드를 피어 클래스에서 재정의해야 합니다. 키 정보를 보고하는 문자열은 지역화해야 할 수 있으므로 하드 코딩된 문자열이 아닌 리소스에서 제공되어야 합니다.

컬렉션을 지원하는 클래스에 대한 피어를 제공하는 경우, 이러한 종류의 컬렉션이 이미 지원되는 기능 클래스와 피어 클래스 모두에서 파생하는 것이 가장 좋습니다. 이렇게 할 수 없는 경우, 자식 컬렉션을 유지하는 컨트롤에 대한 피어는 컬렉션 관련 피어 메서드 GetChildrenCore 를 재정의하여 부모-자식 관계를 UI 자동화 트리에 올바르게 보고해야 할 수 있습니다.

IsContentElementCoreIsControlElementCore 메서드를 구현하여 컨트롤이 데이터 콘텐츠를 포함하는지, 사용자 인터페이스에서 대화형 역할을 수행하는지 (또는 둘 다인지를) 나타냅니다. 기본적으로 두 메서드 모두 true를 반환합니다. 이러한 설정에서는 화면 읽기 프로그램과 같은 보조 기술의 유용성이 향상되며, 이러한 메서드를 사용하여 자동화 트리를 필터링할 수 있습니다. 만약 GetPatternCore 메서드가 하위 요소 피어를 처리하는 패턴을 전송하면, 하위 요소 피어의 IsControlElementCore 메서드는 false 를 반환하여 자동화 트리의 하위 요소 피어를 숨길 수 있습니다.

텍스트 레이블 부분이 텍스트가 아닌 부분에 대한 정보를 제공하거나 컨트롤이 UI의 다른 컨트롤과 알려진 레이블 관계에 함께 있는 레이블 지정 시나리오를 몇몇 컨트롤을 통해 지원할 수 있습니다. 유용한 클래스 기반 동작을 제공할 수 있는 경우, GetLabeledByCore 를 재정의하여 동작을 제공할 수 있습니다.

GetBoundingRectangleCoreGetClickablePointCore는 주로 자동화된 테스트 시나리오에 사용됩니다. 컨트롤에 대한 자동화된 테스트를 지원하려는 경우 이러한 메서드를 재정의할 수 있습니다. 이는 사용자가 좌표 공간에서 클릭하는 위치가 범위에 다른 영향을 미치기 때문에 단일 지점만 제안할 수 없는 범위 형식 컨트롤에 적합할 수 있습니다. 예를 들어, 기본 ScrollBar 자동화 피어는 GetClickablePointCore 를 재정의하여 "숫자가 아님" Point 값을 반환합니다.

GetLiveSettingCore는 UI 자동화의 LiveSetting 값에 대한 컨트롤 기본값에 영향을 줍니다. 컨트롤이 AutomationLiveSetting.Off이외의 값을 반환하도록 하려면 이 값을 재정의하면 됩니다. 만약 LiveSetting 이 나타내는 항목에 대한 자세한 내용을 원하시면 AutomationProperties.LiveSetting을 참조하세요.

GetOrientationCore 를 재정의할 수 있는 경우는 AutomationOrientation에 매핑할 수 있는 설정 가능한 방향 속성이 컨트롤에 있는 경우입니다. 이 ScrollBarAutomationPeerSliderAutomationPeer 클래스는 이 작업을 수행합니다.

FrameworkElementAutomationPeer의 기본 구현

프레임워크 수준에서 정의된 다양한 레이아웃 및 동작 속성에서 해석할 수 있는 몇 가지 UI 자동화 정보를 FrameworkElementAutomationPeer 기본 구현이 제공합니다.

  • GetBoundingRectangleCore: 알려진 레이아웃 특성을 기준으로 Rect 구조를 반환합니다. 0값 Rect 를 반환하는 경우는 IsOffscreentrue인 경우입니다.
  • GetClickablePointCore: 0이 아닌 BoundingRectangle이 있는 한 알려진 레이아웃 특성을 기준으로 Point 구조를 반환합니다.
  • GetNameCore: 여기서 요약할 수 있는 것보다 광범위한 동작이 있습니다. GetNameCore를 참조하세요. 기본적으로, ContentControl 의 잘 알려진 콘텐츠 또는 콘텐츠가 있는 관련 클래스에서 문자열 변환을 시도합니다. 또한 LabeledBy에 대한 값이 있는 경우, 해당 항목의 Name 값은 Name으로 사용됩니다.
  • HasKeyboardFocusCore: 소유자의 FocusStateIsEnabled 속성을 기준으로 평가됩니다. 컨트롤이 아닌 요소는 항상 false를 반환합니다.
  • IsEnabledCore: Control인 경우 소유자의 IsEnabled 속성을 기준으로 평가됩니다. 컨트롤이 아닌 요소는 항상 true를 반환합니다. 이는 소유자가 기존의 상호 작용 측면에서 활성화 되어있음을 의미하지는 않습니다. 즉, 소유자가 IsEnabled 속성을 갖지 않았음에도 불구하고 피어를 사용할 수 있습니다.
  • IsKeyboardFocusableCore: 소유자가 Control이면 true를 반환하고, 그렇지 않으면 false입니다.
  • IsOffscreenCore: 소유자 요소나 부모 중 하나에서 VisibilityCollapsed이면 IsOffscreentrue 값인 경우와 같습니다. 예외: 소유자의 부모가 아니더라도 Popup 객체를 볼 수 있습니다.
  • SetFocusCore: Focus를 호출합니다.
  • GetParent: 소유자에서 FrameworkElement.Parent를 호출하고 적절한 피어를 조회합니다. "Core" 메서드를 사용하는 재정의 쌍이 아니므로 이 동작을 변경할 수 없습니다.

참고 항목

기본 UWP 피어는 실제 UWP 코드를 사용하는 것이 아니라 UWP를 구현하는 내부 네이티브 코드를 사용하여 동작을 구현합니다. CLR(공용 언어 런타임) 리플렉션 또는 기타 기술을 통해 구현의 코드 또는 논리를 볼 수 없습니다. 기본 피어 동작의 하위 클래스별 재정의에 대한 고유 참조 페이지도 표시되지 않습니다. 예를 들어, GetNameCore 에 대한 동작이 TextBoxAutomationPeer에 있을 수 있으나, AutomationPeer.GetNameCore 참조 페이지에는 설명이 없고 TextBoxAutomationPeer.GetNameCore에 대한 참조 페이지가 없습니다. 심지어 TextBoxAutomationPeer.GetNameCore 참조 페이지도 없습니다. 대신 가장 즉각적인 피어 클래스에 대한 참조 항목을 읽고 설명 섹션에서 구현 정보를 찾습니다.

Peers 및 AutomationProperties

자동화 피어는 컨트롤의 접근성 관련 정보에 적절한 기본값을 제공해야 합니다. 컨트롤을 사용하는 모든 앱 코드는 컨트롤 인스턴스에 AutomationProperties 결합속성 값을 포함하여 해당 동작 중 일부를 재정의할 수 있습니다. 호출자는 기본 컨트롤 또는 사용자 지정 컨트롤에 대해 이 작업을 수행할 수 있습니다. 예를 들어 다음 XAML은 두 개의 사용자 지정된 UI 자동화 속성이 있는 단추를 만듭니다. <Button AutomationProperties.Name="Special" AutomationProperties.HelpText="This is a special button."/>

만약 AutomationProperties 결합속성에 대한 자세한 정보를 원하시면 기본 접근성 정보를 참조하세요.

일부 AutomationPeer 메서드는 UI 자동화 공급자가 정보를 보고하는 방법에 대한 일반적인 계약 때문에 존재하지만 이러한 메서드는 일반적으로 제어 피어에서 구현되지 않습니다. 이 정보는 특정 UI의 컨트롤을 사용하는 앱 코드에 적용되는 AutomationProperties 값에 의해 제공되어야 하기 때문입니다. 예를 들어, 대부분의 앱은 AutomationProperties.LabeledBy 값을 UI에서 서로 다른 두 컨트롤 간의 레이블 지정 관계를 정의합니다. 그러나 LabeledByCore 는 헤더 파트를 사용하여 데이터 필드 파트에 레이블을 지정하거나, 컨테이너를 사용하여 항목에 레이블을 지정하거나, 유사한 시나리오와 같이 컨트롤의 데이터 또는 항목 관계를 나타내는 특정 피어에서 구현됩니다.

패턴 구현

expand-collapse에 대한 컨트롤 패턴 인터페이스를 구현하여 확장 축소 동작을 구현하는 컨트롤에 대한 피어를 작성하는 방법을 살펴보겠습니다. 피어는 GetPatternPatternInterface.ExpandCollapse값으로 호출될 때마다 자신을 반환하여 확장-축소 동작에 대한 접근성을 사용하도록 설정해야 합니다. 그런 다음 피어는 해당 패턴(IExpandCollapseProvider)에 대한 공급자 인터페이스를 상속하고 해당 공급자 인터페이스의 각 멤버에 대한 구현을 제공해야 합니다. 이 경우 인터페이스에는 재정의할 멤버 3개인 Expand, Collapse, ExpandCollapseState가 있습니다.

클래스 자체의 API 디자인에서 접근성을 미리 계획하는 것이 유용합니다. UI에서 작업하는 사용자와의 일반적인 상호 작용의 결과로서 또는 자동화 공급자 패턴을 통해 잠재적으로 요청되는 동작이 있을 때마다, UI 응답 또는 자동화 패턴이 호출할 수 있는 단일 메서드를 제공합니다. 예를 들어, 컨트롤을 확장하거나 축소할 수 있는 유선 이벤트 처리기가 컨트롤에 있고 해당 작업에 해당하는 키보드가 있는 버튼 부분이 있는 경우, 이러한 이벤트 처리기가 호출하는 Expand or Collapse 구현은 IExpandCollapseProvider 에 대한 것으로 피어에 있습니다. 일반적인 논리 메서드를 사용하면 동작이 호출된 방식에 관계없이 컨트롤의 시각적 상태가 균일한 방식으로 논리적 상태를 보여주게끔 업데이트할 수 있는 유용한 방법이 될 수도 있습니다.

일반적인 구현은 공급자 API가 런타임에 컨트롤 인스턴스에 대한 액세스를 위해 소유자 를 먼저 호출하는 것을 뜻합니다. 그런 다음, 필요로 하는 동작 메서드를 해당 객체에 호출할 수 있습니다.

public class IndexCardAutomationPeer : FrameworkElementAutomationPeer, IExpandCollapseProvider {
    private IndexCard ownerIndexCard;
    public IndexCardAutomationPeer(IndexCard owner) : base(owner)
    {
         ownerIndexCard = owner;
    }
}

대체 구현은 컨트롤 자체가 해당 피어를 참조할 수 있다는 것입니다. 이는 컨트롤에서 자동 이벤트를 발생시키는 경우 일반적인 패턴입니다. 왜냐하면 RaiseAutomationEvent 메서드가 피어 메서드이기 때문입니다.

UI 자동화 이벤트

UI 자동화 이벤트는 다음 범주로 해당합니다.

이벤트 설명
속성 변경 UI 자동화 요소 또는 컨트롤 패턴의 속성이 변경될 때 발생합니다. 예를 들어 클라이언트가 앱의 체크박스 컨트롤을 모니터링해야 하는 경우, ToggleState 속성에서 속성 변경 이벤트에 대해 등록할 수 있습니다.. 확인란 컨트롤을 선택하거나 선택 취소하면, 공급자가 이벤트를 발생시키며 클라이언트는 필요에 따라 동작할 수 있습니다.
요소 작업 사용자나 프로그래밍 작업으로 결과가 바뀌면(예: 버튼이 Invoke 패턴을 통해 클릭되거나 호출되는 경우) 발생합니다.
구조 변경 UI 자동화 트리의 구조가 변경될 때 발생합니다. 새 UI 항목이 데스크톱에서 표시되거나 숨겨지거나 제거되면 구조가 변경됩니다.
전역 변경 내용 요소 간에 포커스가 전환되거나 자식 창이 닫히는 경우와 같이, 클라이언트에 전역적으로 영향을 미치는 작업이 이루어지면 발생합니다. 일부 이벤트는 UI 상태가 변경된 것을 의미하지 않을 수도 있습니다. 예를 들어, 사용자가 텍스트 입력 필드를 탭한 후 필드를 업데이트하기 위해 버튼을 클릭하면, TextChanged 이벤트가 실제로 사용자가 텍스트를 변경하지 않았어도 발생합니다. 이벤트를 처리할 때 클라이언트 애플리케이션이 작업을 수행하기 전에 실제로 변경된 사항이 있는지 여부를 확인해야 할 수도 있습니다.

AutomationEvents 식별자

UI 자동화 이벤트는 AutomationEvents 값에 의해 식별됩니다. 열거형의 값은 이벤트의 종류를 고유하게 식별합니다.

이벤트 발생

UI 자동화 클라이언트는 자동화 이벤트를 구독할 수 있습니다. 자동화 피어 모델에서, 사용자 지정 컨트롤의 피어는 RaiseAutomationEvent 메서드를 호출하여 접근성과 관련된 컨트롤 상태에 대한 변경 내용을 보고해야 합니다. 마찬가지로 키 UI 자동화 속성 값이 변경되면, 사용자 지정 컨트롤 피어는 RaisePropertyChangedEvent 메서드를 호출해야 합니다.

다음 코드 예제에서는 컨트롤 정의 코드 내에서 피어 객체를 가져오고 메서드를 호출하여 해당 피어에서 이벤트를 발생시키는 방법을 보여 줍니다. 최적화 방법으로서, 코드는 이 이벤트 유형에 대한 수신기가 있는지 확인합니다. 수신기가 있는 경우에만 이벤트가 발생되고 피어 객체가 만들어지면 불필요한 오버헤드를 방지하고 컨트롤이 응답 가능한 상태를 유지하는 데 도움이 됩니다.

if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
    NumericUpDownAutomationPeer peer =
        FrameworkElementAutomationPeer.FromElement(nudCtrl) as NumericUpDownAutomationPeer;
    if (peer != null)
    {
        peer.RaisePropertyChangedEvent(
            RangeValuePatternIdentifiers.ValueProperty,
            (double)oldValue,
            (double)newValue);
    }
}

피어 탐색

자동화 피어를 찾은 후, 피어 객체의 GetChildrenGetParent 메서드를 호출하여 앱의 피어 구조를 UI 자동화 클라이언트가 탐색할 수 있습니다. 컨트롤 내 UI 요소 간 탐색은 피어의 GetChildrenCore 메서드 구현으로 지원됩니다. UI 자동화 시스템은 이 메서드를 호출하여 컨트롤 내에 포함된 하위 요소의 트리를 작성합니다(예: 목록 상자의 목록 항목). 기본 GetChildrenCore 메서드는 FrameworkElementAutomationPeer 에서 요소의 시각적 트리를 트래버스하여 자동화 피어의 트리를 빌드합니다. 사용자 지정 컨트롤은 이 메서드를 재정의하여 다르게 표현되는 자식 요소를 자동화 클라이언트에 노출하며, 정보를 전달하거나 사용자 상호 작용을 허용하는 요소의 자동화 피어를 반환합니다.

텍스트 패턴에 대한 네이티브 자동화 지원

일부 기본 UWP 앱 자동화 피어는 텍스트 패턴(PatternInterface.Text)에 대한 컨트롤 패턴 지원을 제공합니다. 그러나 네이티브 메서드를 통해 이 지원을 제공하며, 관련된 피어는 (관리되는) 상속에서 ITextProvider 인터페이스를 기록하지 않습니다. 그러나 관리되거나 관리되지 않는 UI 자동화 클라이언트가 패턴에 대한 피어를 쿼리하는 경우, 텍스트 패턴에 대한 지원을 보고하고 클라이언트 API가 호출될 때 패턴의 일부에 대한 동작을 제공합니다.

UWP 앱 텍스트 컨트롤 중 하나에서 파생되고 텍스트 관련 피어 중 하나에서 파생되는 사용자 지정 피어를 만들려는 경우, 피어에 대한 주의 섹션을 확인하여 패턴에 대한 네이티브 수준의 지원에 대해 자세히 알아봅니다. 관리되는 공급자 인터페이스 구현에서 기본 구현을 호출하는 경우 사용자 지정 피어의 네이티브 기본 동작에 액세스할 수 있지만, 피어와 해당 소유자 컨트롤의 네이티브 인터페이스 둘 다 노출되지 않으므로 기본 구현에서 수행하는 작업을 수정하기가 어렵습니다. 일반적으로 기본 구현을 있는 그대로 사용하거나(기본 호출에만 해당) 기능을 자체 관리 코드로 완전히 바꾸고 기본 구현을 호출하지 않아야 합니다. 후자는 고급 시나리오에 해당합니다. 해당 프레임워크를 사용할 때 접근성 요구 사항을 지원하기 위해 컨트롤에서 사용하는 텍스트 서비스 프레임워크에 대해 잘 알고 있어야 합니다.

AutomationProperties.AccessibilityView

사용자 지정 피어를 제공하는 것 외에도 XAML의 AutomationProperties.AccessibilityView 를 설정하여 모든 컨트롤 인스턴스에 대한 트리 뷰 표현을 조정할 수 있습니다. 피어 클래스의 일부로 구현되지는 않지만 사용자 지정 컨트롤 또는 사용자 지정 템플릿에 대한 전반적인 접근성 지원을 사용할 수 있으므로 여기서 언급합니다.

전체 컨트롤의 접근성 보기에 의미 있는 영향을 주지 않으므로 템플릿의 특정 컨트롤을 UI 자동화 보기에서 의도적으로 생략하는 것이 AutomationProperties.AccessibilityView 를 사용하는 기본 시나리오입니다. 이를 방지하려면, AutomationProperties.AccessibilityView "Raw"로 설정합니다.

자동화 피어에서 예외 throw

자동화 피어 지원을 위해 구현하는 API는 예외를 throw할 수 있습니다. 수신 대기 중인 모든 UI 자동화 클라이언트는 대부분의 예외가 throw된 후에도 계속 진행할 수 있을 만큼 강력할 것으로 예상됩니다. 수신기가 사용자 고유의 앱이 아닌 다른 앱을 포함하는 올업 자동화 트리를 보고 있을 가능성이 높으며, 클라이언트가 API를 호출했을 때 트리의 한 영역에서 피어 기반 예외가 발생했기 때문에 전체 클라이언트를 다운하는 것을 용납할 수 없는 클라이언트 디자인입니다.

피어에 전달되는 매개 변수의 경우 입력의 유효성을 검사할 수 있으며, 예를 들어 ArgumentNullException 을 throw하려면 null 이 전달되고 구현에 유효한 값이 아니어야 합니다. 그러나 피어에서 수행하는 후속 작업이 있는 경우, 피어와 호스팅 컨트롤의 상호 작용에 비동기 문자가 있다는 점을 기억하세요. 피어가 수행하는 모든 것이 컨트롤의 UI 스레드를 반드시 차단하지는 않습니다(또한 그렇지 않아야 합니다). 따라서 피어를 만들 때 또는 자동화 피어 메서드가 처음 호출되었을 때 객체를 사용할 수 있거나 특정 속성이 있는 상황이 있을 수 있지만, 그 동안 컨트롤 상태는 변경되었습니다. 이러한 경우 공급자가 throw할 수 있는 전용 예외가 두 가지 있습니다.

  • API가 전달한 원래 정보를 기반으로 피어의 소유자 또는 관련한 피어 요소에 액세스할 수 없을 때 ElementNotAvailableException 를 throw합니다. 예를 들어 메서드를 실행하려는 피어가 있을 수 있지만 닫힌 모달 대화 상자와 같이 UI에서 소유자가 제거되었습니다. .NET이 아닌 클라이언트의 경우 이는 UIA\_E\_ELEMENTNOTAVAILABLE에 매핑됩니다.
  • 여전히 소유자가 있는 경우, ElementNotEnabledException 를 throw하지만, 해당 소유자가 피어가 수행하려는 특정 프로그래밍 변경 일부를 차단하는 IsEnabled=false 모드에 있습니다. .NET이 아닌 클라이언트의 경우 이는 UIA\_E\_ELEMENTNOTENABLED에 매핑됩니다.

이 외에도 피어는 피어 지원에서 throw하는 예외에 대해 상대적으로 보수적이어야 합니다. 대부분의 클라이언트는 피어의 예외를 처리하고 사용자가 클라이언트와 상호 작용할 때 수행할 수 있는 실행 가능한 선택 항목으로 전환할 수 없습니다. 따라서 경우에 따라 작업 없이 피어 구현 내에서 다시 throw하지 않고 예외를 catch하는 것이 피어가 수행하려고 할 때마다 피어가 예외를 throw하는 것보다 더 나은 전략입니다. 또한 대부분의 UI 자동화 클라이언트는 관리 코드로 작성되어있지 않습니다. 대부분은 COM으로 작성되었으며 피어 액세스로 이어지는 UI 자동화 클라이언트 메서드를 호출할 때마다 HRESULT에서 S_OK를 확인하기만 합니다.