리모콘, 키보드 및 D 패드
포커스 탐색을 사용하여 Windows 앱에서 포괄적이고 일관된 상호 작용 환경과 키보드 전원 사용자, 장애가 있는 사용자 및 기타 접근성 요구 사항뿐만 아니라 텔레비전 화면 및 Xbox One의 10피트 환경을 위한 사용자 지정 컨트롤을 제공합니다.
개요
포커스 탐색은 사용자가 키보드, 게임 패드 또는 원격 제어를 사용하여 Windows 애플리케이션의 UI를 탐색하고 상호 작용할 수 있도록 하는 기본 메커니즘을 나타냅니다.
비고
입력 디바이스는 일반적으로 터치, 터치 패드, 펜 및 마우스와 같은 포인팅 디바이스와 키보드, 게임 패드 및 원격 제어와 같은 비 포인팅 디바이스로 분류됩니다.
이 항목에서는 비 포인팅 입력 형식을 사용하는 사용자를 위해 Windows 애플리케이션을 최적화하고 사용자 지정 상호 작용 환경을 빌드하는 방법을 설명합니다.
PC의 Windows 앱에서 사용자 지정 컨트롤에 대한 키보드 입력에 초점을 맞추고 있지만 터치 키보드 및 OSK(화상 키보드)와 같은 소프트웨어 키보드, Windows 내레이터와 같은 접근성 도구 지원, 10피트 환경 지원 등 잘 설계된 키보드 환경도 중요합니다.
포인팅 디바이스에 대한 Windows 애플리케이션에서 사용자 지정 환경을 빌드하는 방법에 대한 지침은 포인터 입력 참조하세요.
키보드용 앱 및 환경을 빌드하는 방법에 대한 자세한 내용은 키보드 상호 작용을 참조하세요.
일반 지침
사용자 상호 작용이 필요한 UI 요소만 포커스 탐색을 지원해야 하며, 정적 이미지와 같은 작업이 필요하지 않은 요소는 키보드 포커스가 필요하지 않습니다. 화면 읽기 프로그램 및 유사한 접근성 도구는 포커스 탐색에 포함되지 않은 경우에도 이러한 정적 요소를 계속 알려 줍니다.
마우스 또는 터치와 같은 포인터 디바이스를 사용하여 탐색하는 것과 달리 포커스 탐색은 선형이라는 점을 기억해야 합니다. 포커스 탐색을 구현할 때는 사용자가 애플리케이션과 상호 작용하는 방법과 논리적 탐색을 고려해야 합니다. 대부분의 경우 사용자 지정 포커스 탐색 동작은 사용자 문화권의 기본 읽기 패턴을 따르는 것이 좋습니다.
다른 포커스 탐색 고려 사항은 다음과 같습니다.
- 컨트롤이 논리적으로 그룹화되었나요?
- 더 중요한 컨트롤 그룹이 있나요?
- 그렇다면 해당 그룹에 하위 그룹이 포함되어 있나요?
- 레이아웃에 사용자 지정 방향 탐색(화살표 키) 및 탭 순서가 필요한가요?
접근성 엔지니어링 소프트웨어
키보드용 2D 방향 탐색
컨트롤 또는 컨트롤 그룹의 2D 내부 탐색 영역을 "방향 영역"이라고 합니다. 포커스가 이 개체로 이동하면 키보드 화살표 키(왼쪽, 오른쪽, 위쪽 및 아래쪽)를 사용하여 방향 영역 내의 자식 요소 사이를 탐색할 수 있습니다.
제어 그룹의 방향 영역
XYFocusKeyboardNavigation 속성(가능한 값으로 자동, 사용또는 사용 안 함)을 이용하여 2차원 내부 탐색을 키보드 화살표 키로 관리할 수 있습니다.
비고
탭 순서는 이 속성의 영향을 받지 않습니다. 혼동되는 탐색 환경을 방지하려면, 애플리케이션의 탭 탐색 순서에서 방향 영역 의 자식 요소를 명시적으로 지정하고,에서는 피할 것을 권장합니다. 요소의 탭 동작에 대한 자세한 내용은 UIElement.TabFocusNavigation 및 TabIndex 속성을 참조하세요.
자동(기본 동작)
Auto로 설정하면 방향 탐색 동작은 요소의 조상 또는 상속 계층 구조에 의해 결정됩니다. 모든 상위 항목이 기본 모드(자동
비활성화
XYFocusKeyboardNavigation을(를) 사용하지 않음으로 설정하여 컨트롤 및 해당 자식 요소에 대한 방향 탐색을 차단합니다.
XYFocusKeyboardNavigation 사용 안 함 동작
이 예제에서 기본 StackPanel(ContainerPrimary)는 XYFocusKeyboardNavigation이 Enabled로 설정되어 있습니다. 모든 자식 요소는 이 설정을 상속하며, 화살표 키를 사용하여 이동할 수 있습니다. 그러나 B3 및 B4 요소는 보조 StackPanel(ContainerSecondary)에 있고, 여기에서 XYFocusKeyboardNavigation이 사용 안 함으로 설정되어 있어 기본 컨테이너를 재정의하며, 이로 인해 화살표 키를 사용한 자체 및 자식 요소 간의 탐색이 비활성화됩니다.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="75"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
XYFocusKeyboardNavigation="Enabled"
KeyDown="ContainerPrimary_KeyDown"
Orientation="Horizontal"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus" />
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus" />
<StackPanel Name="ContainerSecondary"
XYFocusKeyboardNavigation="Disabled"
Orientation="Horizontal"
BorderBrush="Red"
BorderThickness="2">
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus" />
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus" />
</StackPanel>
</StackPanel>
</Grid>
활성화됨
XYFocusKeyboardNavigation을(를) 사용 가능으로 설정하여 컨트롤과 각 UIElement 자식 개체에 대한 2D 방향 탐색을 지원합니다.
설정하면 화살표 키를 사용한 탐색이 방향 영역 내의 요소로 제한됩니다. 탭 순서 계층 구조를 통해 모든 컨트롤에 액세스할 수 있으므로 탭 탐색은 영향을 받지 않습니다.
XYFocusKeyboardNavigation 사용 동작
이 예제에서 기본 StackPanel(ContainerPrimary)는 XYFocusKeyboardNavigation이 Enabled로 설정되어 있습니다. 모든 자식 요소는 이 설정을 상속하며, 화살표 키를 사용하여 이동할 수 있습니다. B3 및 B4 요소는 보조 StackPanel(ContainerSecondary)에 위치하고 있으며, 이곳에서 XYFocusKeyboardNavigation이 설정되지 않았기 때문에 기본 컨테이너의 설정을 상속받습니다. B5 요소는 선언된 방향 영역 내에 있지 않으며 화살표 키 탐색을 지원하지 않지만 표준 탭 탐색 동작을 지원합니다.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Center">
<StackPanel Name="ContainerPrimary"
XYFocusKeyboardNavigation="Enabled"
KeyDown="ContainerPrimary_KeyDown"
Orientation="Horizontal"
BorderBrush="Green"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus" Margin="5" />
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus" />
<StackPanel Name="ContainerSecondary"
Orientation="Horizontal"
BorderBrush="Red"
BorderThickness="2"
Margin="5">
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5" />
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5" />
</StackPanel>
</StackPanel>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5" />
</StackPanel>
</Grid>
여러 수준의 중첩 방향 영역을 가질 수 있습니다. 모든 부모 요소에 XYFocusKeyboardNavigation이 Enabled로 설정된 경우 내부 탐색 영역 경계는 무시됩니다.
다음은 2D 방향 탐색을 명시적으로 지원하지 않는 요소 내의 중첩된 두 방향 영역의 예입니다. 이 경우 두 개의 중첩된 영역 간에 방향 탐색이 지원되지 않습니다.
XYFocusKeyboardNavigation 활성화됨 및 중첩된 동작
다음은 세 가지 중첩 방향 영역의 보다 복잡한 예입니다.
- B1에 포커스가 있는 경우, XYFocusKeyboardNavigation이 Disabled로 설정된 방향 영역 경계 때문에 B5로만 탐색할 수 있으며, 반대로 B5에 포커스가 있을 때도 B1로만 탐색할 수 있습니다. 이 설정으로 인해 화살표 키를 사용하여 B2, B3 및 B4로는 접근할 수 없습니다.
- B2에 포커스가 있는 경우 방향 영역 경계가 B1, B4 및 B5에 대한 화살표 키 탐색을 방지하므로 B3만 탐색할 수 있습니다(그 반대의 경우도 마찬가지임).
- B4에 포커스가 있는 경우 Tab 키를 사용하여 컨트롤 간을 이동해야 합니다.
XYFocusKeyboardNavigation 기능 사용 및 복잡한 중첩 동작
탭 탐색
화살표 키는 컨트롤 또는 컨트롤 그룹의 2D 방향 탐색 위틴에 사용할 수 있지만 Tab 키를 사용하여 Windows 애플리케이션의 모든 컨트롤을 탐색할 수 있습니다.
모든 대화형 컨트롤은 기본적으로 Tab 키 탐색을 지원하며 (IsEnabled 및 IsTabStop 속성이 true인 경우), 애플리케이션의 컨트롤 레이아웃에 따라 파생된 논리적 탭 순서가 있습니다. 그러나 기본 순서가 시각적 순서에 반드시 해당하는 것은 아닙니다. 실제 표시 위치는 부모 레이아웃 컨테이너 및 레이아웃에 영향을 주도록 자식 요소에 설정할 수 있는 특정 속성에 따라 달라질 수 있습니다.
애플리케이션에서 포커스를 이동하는 사용자 지정 탭 순서를 사용하지 않습니다. 예를 들어 폼의 컨트롤 목록에는 로캘에 따라 위에서 아래로, 왼쪽에서 오른쪽으로 흐르는 탭 순서가 있어야 합니다.
이 섹션에서는 이 탭 순서를 앱에 맞게 완전히 사용자 지정할 수 있는 방법을 설명합니다.
탭 탐색 동작 설정
UIElement의 TabFocusNavigation 속성은 전체 개체 트리(또는 방향 영역)에 대한 탭 탐색 동작을 지정합니다.
비고
ControlTemplate를 사용하여 모양을 정의하지 않는 개체의 경우 Control.TabNavigation 속성 대신 이 속성을 사용하십시오.
이전 섹션에서 설명한 것처럼, 혼란스러운 탐색 환경을 방지하기 위해서는 방향 영역 의 자식 요소가이 아니라 애플리케이션의 탭 탐색 순서에 명시적으로 지정되는 것이 좋습니다. 요소의 탭 동작에 대한 자세한 내용은 UIElement.TabFocusNavigation 및 TabIndex 속성을 참조하세요.
Windows 10 크리에이터스 업데이트(빌드 10.0.15063)보다 오래된 버전의 경우 탭 설정이 ControlTemplate 개체로 제한되었습니다. 자세한 내용은 Control.TabNavigation을 참조하세요.
TabFocusNavigation은 KeyboardNavigationMode 형식의 값으로, 다음과 같은 가능한 값들을 갖습니다(이러한 예시는 사용자 지정 컨트롤 그룹이 아니며, 화살표 키를 사용한 내부 탐색이 필요하지 않습니다).
로컬 (기본값) 탭 인덱스는 컨테이너 내의 로컬 하위 트리에서 인식됩니다. 이 예제의 경우 탭 순서는 B1, B2, B3, B4, B5, B6, B7, B1입니다.
"로컬" 탭 탐색 동작
한 번 컨테이너와 모든 자식 요소가 한 번 포커스를 받습니다. 이 예제의 경우 탭 순서는 B1, B2, B7, B1입니다(화살표 키가 있는 내부 탐색도 보여 줍니다).
"한 번" 탭 탐색 동작
주기
포커스는 컨테이너 내의 초기 포커스 가능 요소로 다시 순환합니다. 이 예제의 경우 탭 순서는 B1, B2, B3, B4, B5, B6, B2..."순환" 탭 탐색 동작
다음은 앞의 예제에 대한 코드입니다(TabFocusNavigation ="Cycle"포함).
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
KeyDown="Container_KeyDown"
Orientation="Horizontal"
HorizontalAlignment="Center"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<StackPanel Name="ContainerSecondary"
KeyDown="Container_KeyDown"
XYFocusKeyboardNavigation="Enabled"
TabFocusNavigation ="Cycle"
Orientation="Vertical"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
<Button Name="B7"
Content="B7"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
</Grid>
tabIndex
TabIndex를 사용하여 사용자가 Tab 키를 사용하여 컨트롤을 탐색할 때 요소가 포커스를 받는 순서를 지정합니다. 탭 인덱스가 낮은 컨트롤은 인덱스가 더 높은 컨트롤 앞에 포커스를 받습니다.
컨트롤에 TabIndex 가 지정되지 않은 경우 범위에 따라 시각적 트리에 있는 모든 대화형 컨트롤의 현재 가장 높은 인덱스 값(및 가장 낮은 우선 순위)보다 높은 인덱스 값이 할당됩니다.
컨트롤의 모든 자식 요소는 범위로 간주되며 이러한 요소 중 하나에 자식 요소도 있는 경우 다른 범위로 간주됩니다. 범위의 시각적 트리에서 첫 번째 요소를 선택하여 모호성을 해결합니다.
탭 순서에서 컨트롤을 제외하려면
TabIndex 속성을 설정하여 기본 탭 순서를 재정의합니다.
비고
TabIndex는 UIElement.TabFocusNavigation 및 Control.TabNavigation와 동일하게 작동합니다.
여기서는 특정 요소에 대한 TabIndex 속성의 포커스 탐색에 영향을 줄 수 있는 방법을 보여 드립니다.
TabIndex 동작 사용하여 "로컬" 탭 탐색
TabIndex 동작 사용하여 "로컬" 탭 탐색
앞의 예제에는 두 가지 범위가 있습니다.
- B1, 방향 영역(B2 - B6) 및 B7
- 방향 영역(B2 - B6)
B3(방향 영역)에 포커스가 있으면 범위가 변경되고 탭 탐색이 방향 영역으로 전송됩니다. 여기서 후속 포커스에 가장 적합한 후보가 식별됩니다. 이 경우 B2 다음에 B4, B5 및 B6이 잇습니다. 그런 다음 범위가 다시 변경되고 포커스가 B1로 이동합니다.
이 예제의 코드는 다음과 같습니다.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
KeyDown="Container_KeyDown"
Orientation="Horizontal"
HorizontalAlignment="Center"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
TabIndex="1"
ToolTipService.ToolTip="TabIndex = 1"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<StackPanel Name="ContainerSecondary"
KeyDown="Container_KeyDown"
TabFocusNavigation ="Local"
Orientation="Vertical"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
TabIndex="3"
ToolTipService.ToolTip="TabIndex = 3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
<Button Name="B7"
Content="B7"
TabIndex="2"
ToolTipService.ToolTip="TabIndex = 2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
</Grid>
키보드, 게임 패드 및 원격 제어를 위한 2D 방향 탐색
키보드, 게임 패드, 원격 제어 및 Windows 내레이터와 같은 접근성 도구와 같은 비 포인터 입력 형식은 Windows 애플리케이션의 UI를 탐색하고 상호 작용하기 위한 일반적인 기본 메커니즘을 공유합니다.
이 섹션에서는 기본 탐색 전략을 지정하고 모든 포커스 기반 비 포인터 입력 형식을 지원하는 탐색 전략 속성 집합을 통해 애플리케이션 내에서 포커스 탐색을 미세 조정하는 방법을 설명합니다.
Xbox/TV용 앱 및 환경을 구축하는 방법에 대한 더 일반적인 정보를 보려면 키보드 상호 작용, Xbox 및 TV를 위한 디자인, 그리고 게임패드 및 원격 제어 상호 작용를 참조하세요.
탐색 전략
탐색 전략은 키보드, 게임 패드, 원격 제어 및 다양한 접근성 도구에 적용됩니다.
다음 탐색 전략 속성을 사용하면 화살표 키, 방향 패드(D-패드) 단추 또는 이와 유사한 누름에 따라 포커스를 받는 컨트롤에 영향을 줄 수 있습니다.
- XY포커스업내비게이션전략
- XYFocusDownNavigationStrategy
- XYFocusLeftNavigationStrategy (XY 포커스 왼쪽 네비게이션 전략)
- XY포커스오른쪽네비게이션전략
이러한 속성에는 자동(기본값), 네비게이션 방향 거리, 프로젝션또는 직선 거리 값이 있습니다.
자동으로 설정하면, 요소의 동작은 요소의 상위 요소를 기반하여 동작합니다. 모든 요소가 자동로 설정되면 프로젝션이 사용됩니다.
비고
이전에 포커스가 있는 요소나 탐색 방향의 축에 근접한 요소와 같은 다른 요소는 결과에 영향을 줄 수 있습니다.
프로젝션
프로젝션 전략은 현재 포커스가 있는 요소의 가장자리가 탐색 방향으로
이 예제에서는 각 포커스 탐색 방향이 프로젝션으로 설정됩니다. B3을 우회하여 포커스가 B1에서 B4로 이동하는 방식을 확인합니다. 이는 B3이 프로젝션 영역에 없기 때문입니다. 또한 B1에서 왼쪽으로 이동할 때 포커스 후보가 식별되지 않는 방법도 확인합니다. B1을 기준으로 B2의 위치가 B3을 후보로 제거하기 때문입니다. B3이 B2와 동일한 행에 있는 경우 왼쪽 탐색에 사용할 수 있는 후보가 됩니다. B2는 탐색 방향 축에 대한 방해받지 않는 근접성으로 인해 유력한 후보입니다.
프로젝션 탐색 전략
내비게이션 방향 거리
NavigationDirectionDistance 전략은 탐색 방향의 축에 가장 가까운 요소로 포커스를 이동합니다.
탐색 방향에 해당하는 경계 사각형의 가장자리는 후보 대상을 식별하기 위해 이으로 확장되고, 가로 프로젝션됩니다. 첫 번째 요소가 대상으로 식별됩니다. 여러 후보가 있는 경우 가장 가까운 요소가 대상으로 식별됩니다. 여전히 여러 후보가 있는 경우 맨 위/맨 왼쪽 요소가 후보로 식별됩니다.
NavigationDirectionDistance 내비게이션 방향 거리 전략
직선 거리
RectilinearDistance 전략은 2D 직사각형 거리(Taxicab 기하 도형)를 기반으로 포커스를 가장 가까운 요소로 이동합니다.
각 잠재적 후보자의 주요 거리와 부차적 거리의 합이 최상의 후보자를 식별하는 데 사용됩니다. 동률 상황에서 요청된 방향이 위 또는 아래일 경우, 왼쪽의 첫 번째 요소가 선택되고, 요청된 방향이 왼쪽 또는 오른쪽일 경우, 위쪽의 첫 번째 요소가 선택됩니다.
RectilinearDistance 탐색 전략
이 이미지는 B1에 포커스가 있고 아래쪽이 요청된 방향인 경우 B3이 RectilinearDistance 포커스 후보인 방법을 보여줍니다. 이 예제에 대한 다음 계산을 기반으로 합니다.
- 거리(B1, B3, 아래)는 10 + 0 = 10입니다.
- 거리(B1, B2, 아래쪽)는 0 + 40 = 30입니다.
- 거리(B1, D, 아래쪽)는 30 + 0 = 30입니다.
관련 문서
Windows developer