키보드 액셀러레이터

Hero image of the Surface keyboard

바로 가기 키는 사용자가 앱 UI를 탐색하지 않고도 일반적인 동작이나 명령을 호출할 수 있는 직관적인 방법을 제공하여 Windows 애플리케이션의 사용 편의성과 접근성을 향상시키는 키보드 바로 가기 키입니다.

참고 항목

키보드는 특정 장애(키보드 접근성 참조)가 있는 사용자에게 필수이며, 앱과 좀 더 효과적으로 상호 작용하는 수단으로 키보드를 선호하는 사용자에게도 중요한 도구입니다.

키보드 바로 가기 키를 사용하여 Windows 애플리케이션의 UI를 탐색하는 방법에 대한 자세한 내용은 선택키를 참조하세요.

사용자 고유의 사용자 지정 바로 가기 키를 만들려면 키보드 이벤트 항목을 참조하세요.

개요

가속기는 보조 키 및 비보조 키의 두 가지 유형의 키로 구성됩니다. 보조 키는 VirtualKeyModifiers를 통해 공개되는 Shift, Menu, Control 및 Windows 키를 포함합니다. 비보조 키는 Delete, F3, 스페이스바, 화살표, Esc, 모든 영숫자 및 문장 부호 키와 같은 VirtualKey입니다.

참고 항목

가속기는 일반적으로 기능 키 F1~F12 또는 하나 이상의 보조 키(CTRL, Shift)와 쌍을 이루는 표준 키 조합을 포함합니다. 예를 들어 사용자가 Ctrl+Shift+M을 누르는 경우 사용자가 M을 누를 때 프레임워크는 보조 키(Ctrl 및 Shift)를 확인하고 가속기가 있으면 가속기를 실행합니다.

많은 XAML 컨트롤이 키보드 가속기 키를 기본적으로 제공합니다. 예를 들어 ListView는 목록의 모든 항목을 선택하기 위해 Ctrl+A를 지원하고, RichEditBox는 텍스트 상자에 Tab을 삽입하기 위해 Ctrl+Tab을 지원합니다. 이러한 기본 제공 키보드 가속기를 컨트롤 가속기라고 하며 포커스가 요소 또는 자식 요소 중 하나에 있는 경우에만 실행됩니다. 여기에 설명된 키보드 가속기 API를 사용하여 정의한 가속기를 앱 가속기라고 합니다.

키보드 가속기는 모든 작업에 사용할 수 있는 것은 아니지만 종종 메뉴에 표시되는 명령과 연결됩니다(메뉴 항목 콘텐츠로 지정해야 함). 가속기는 동일한 메뉴 항목이 없는 작업과 연결할 수도 있습니다. 그러나 사용자는 애플리케이션의 메뉴를 사용하여 사용 가능한 명령 집합을 검색하고 알아보므로, 최대한 쉽게 가속기를 검색할 수 있게 만들어야 합니다(레이블 또는 설정된 패턴을 사용하면 도움이 될 수 있음).

가속기는 자동으로 반복됩니다(예: 사용자가 Ctrl+Shift를 누른 다음, M을 누르고 있으면 M이 해제될 때까지 가속기가 반복적으로 호출됨). 이 동작은 수정할 수 없습니다.

Screenshot of keyboard accelerators in a menu item label.
메뉴 항목 레이블에 설명된 바로 가기 키

키보드 가속기를 사용해야 하는 경우

적합한 경우 UI 어디서나 키보드 가속기를 지정하고 모든 사용자 지정 컨트롤에서 가속기를 지원하는 것이 좋습니다.

  • 키를 한 번에 하나만 누를 수 있거나 마우스 사용에 어려움이 있는 사용자를 포함하여 거동 장애가 있는 사용자를 위해 키보드 가속기로 앱의 접근성을 향상합니다.

    잘 디자인된 키보드 UI는 소프트웨어 접근성의 중요한 측면입니다. 시각 장애가 있거나 특정 운동 장애가 있는 사용자가 앱을 탐색하고 해당 기능과 상호 작용할 수 있습니다. 이러한 사용자는 마우스를 조작할 수 없으며 대신 키보드 개선 도구, 화상 키보드, 화면 확대기, 화면 읽기 프로그램 및 음성 입력 유틸리티와 같은 다양한 보조 기술에 의존할 수 있습니다. 이러한 사용자에게는 포괄적인 명령 범위가 매우 중요합니다.

  • 키보드로 조작하는 것을 선호하는 고급 사용자를 위해 키보드 가속기로 앱의 사용 편의성을 향상합니다.

    숙련된 사용자는 키보드 기반 명령을 더 빠르게 입력할 수 있고 키보드에서 손을 떼지 않아도 되기 때문에 키보드를 선호하는 경향이 강합니다. 이러한 사용자의 경우 효율성과 일관성이 중요합니다. 포괄성은 가장 자주 사용되는 명령에만 중요합니다.

키보드 가속기 지정

KeyboardAccelerator API를 사용하여 Windows 앱에서 키보드 가속기를 만들 수 있습니다. 이러한 API를 사용하면 여러 개의 KeyDown 이벤트를 처리하여 키 조합을 감지할 필요가 없으며 앱 리소스에서 가속기를 지역화할 수 있습니다.

앱의 가장 일반적인 동작에 키보드 가속기를 설정하고 메뉴 항목 레이블 또는 도구 설명을 사용하여 문서화하는 것이 좋습니다. 이 예에서는 Rename 및 Copy 명령에 대해서만 키보드 가속기를 선언합니다.

<CommandBar Margin="0,200" AccessKey="M">
  <AppBarButton 
    Icon="Share" 
    Label="Share" 
    Click="OnShare" 
    AccessKey="S" />
  <AppBarButton 
    Icon="Copy" 
    Label="Copy" 
    ToolTipService.ToolTip="Copy (Ctrl+C)" 
    Click="OnCopy" 
    AccessKey="C">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="Control" 
        Key="C" />
    </AppBarButton.KeyboardAccelerators>
  </AppBarButton>

  <AppBarButton 
    Icon="Delete" 
    Label="Delete" 
    Click="OnDelete" 
    AccessKey="D" />
  <AppBarSeparator/>
  <AppBarButton 
    Icon="Rename" 
    Label="Rename" 
    ToolTipService.ToolTip="Rename (F2)" 
    Click="OnRename" 
    AccessKey="R">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="None" Key="F2" />
    </AppBarButton.KeyboardAccelerators>
  </AppBarButton>

  <AppBarButton 
    Icon="SelectAll" 
    Label="Select" 
    Click="OnSelect" 
    AccessKey="A" />
  
  <CommandBar.SecondaryCommands>
    <AppBarButton 
      Icon="OpenWith" 
      Label="Sources" 
      AccessKey="S">
      <AppBarButton.Flyout>
        <MenuFlyout>
          <ToggleMenuFlyoutItem Text="OneDrive" />
          <ToggleMenuFlyoutItem Text="Contacts" />
          <ToggleMenuFlyoutItem Text="Photos"/>
          <ToggleMenuFlyoutItem Text="Videos"/>
        </MenuFlyout>
      </AppBarButton.Flyout>
    </AppBarButton>
    <AppBarToggleButton 
      Icon="Save" 
      Label="Auto Save" 
      IsChecked="True" 
      AccessKey="A"/>
  </CommandBar.SecondaryCommands>

</CommandBar>

Screenshot of a keyboard accelerator in a tooltip.
도구 설명에 설명된 키보드 가속기

UIElement 개체에는 KeyboardAccelerator 컬렉션, KeyboardAccelerators가 있으며 여기에서 사용자 지정 KeyboardAccelerator 개체를 지정하고 키보드 가속기에 대한 키 입력을 정의합니다.

참고 항목

단일 키(A, Delete, F2, 스페이스바, Esc, 멀티미디어 키) 가속기 및 다중 키 가속기(Ctrl+Shift+M)가 지원됩니다. 하지만 게임 패드 가상 키는 지원되지 않습니다.

범위가 지정된 가속기

특정 범위에서만 작동하는 가속기도 있고 앱 전체에서 작동하는 가속기도 있습니다.

예를 들어 Microsoft Outlook에는 다음과 같은 가속기가 있습니다.

  • Ctrl+B, Ctrl+I 및 ESC는 이메일 보내기 양식의 범위에서만 작동합니다.
  • Ctrl+1 및 Ctrl+2는 앱 전체에서 작동합니다.

상황에 맞는 메뉴

상황에 맞는 메뉴 작업은 텍스트 편집기에서 선택한 문자 또는 재생 목록의 노래와 같은 특정 영역이나 요소에만 영향을 미칩니다. 이러한 이유로 상황에 맞는 메뉴 항목의 키보드 가속기 범위를 상황에 맞는 메뉴의 부모로 설정하는 것이 좋습니다.

ScopeOwner 속성을 사용하여 키보드 가속기의 범위를 지정합니다. 이 코드는 범위가 지정된 키보드 가속기를 사용하여 ListView에 상황에 맞는 메뉴를 구현하는 방법을 보여줍니다.

<ListView x:Name="MyList">
  <ListView.ContextFlyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="Share" Icon="Share"/>
      <MenuFlyoutItem Text="Copy" Icon="Copy">
        <MenuFlyoutItem.KeyboardAccelerators>
          <KeyboardAccelerator 
            Modifiers="Control" 
            Key="C" 
            ScopeOwner="{x:Bind MyList }" />
        </MenuFlyoutItem.KeyboardAccelerators>
      </MenuFlyoutItem>
      
      <MenuFlyoutItem Text="Delete" Icon="Delete" />
      <MenuFlyoutSeparator />
      
      <MenuFlyoutItem Text="Rename">
        <MenuFlyoutItem.KeyboardAccelerators>
          <KeyboardAccelerator 
            Modifiers="None" 
            Key="F2" 
            ScopeOwner="{x:Bind MyList}" />
        </MenuFlyoutItem.KeyboardAccelerators>
      </MenuFlyoutItem>
      
      <MenuFlyoutItem Text="Select" />
    </MenuFlyout>
    
  </ListView.ContextFlyout>
    
  <ListViewItem>Track 1</ListViewItem>
  <ListViewItem>Alternative Track 1</ListViewItem>

</ListView>

MenuFlyoutItem.KeyboardAccelerators 요소의 ScopeOwner 특성은 가속기를 전역이 아닌 지정된 범위로 표시합니다(기본값은 null 또는 전역). 자세한 내용은 이 항목의 후반부에 있는 바로 가기 해결 섹션을 참조하세요.

키보드 가속기 호출

KeyboardAccelerator 개체는 UI 자동화(UIA) 컨트롤 패턴을 사용하여 가속기가 호출될 때 작업을 수행합니다.

UIA [컨트롤 패턴]은 공통적인 컨트롤 기능을 공개합니다. 예를 들어 Button 컨트롤은 Invoke 컨트롤 패턴을 구현하여 Click 이벤트를 지원합니다(일반적으로 컨트롤은 클릭, 두 번 클릭 또는 Enter, 미리 정의된 키보드 바로 가기 키 또는 다른 키 조합을 눌러서 호출됨). 키보드 가속기를 사용하여 컨트롤을 호출하면 XAML 프레임워크는 컨트롤이 Invoke 컨트롤 패턴을 구현하는지 확인하고, 구현하는 경우 이를 활성화합니다(KeyboardAcceleratorInvoked 이벤트를 수신할 필요는 없음).

다음 예제에서는 Button이 Invoke 패턴을 구현하므로 Control+S가 Click 이벤트를 트리거합니다.

<Button Content="Save" Click="OnSave">
  <Button.KeyboardAccelerators>
    <KeyboardAccelerator Key="S" Modifiers="Control" />
  </Button.KeyboardAccelerators>
</Button>

요소가 여러 컨트롤 패턴을 구현하는 경우 하나만 가속기를 통해 활성화할 수 있습니다. 컨트롤 패턴의 우선 순위는 다음과 같습니다.

  1. Invoke(Button)
  2. Toggle(Checkbox)
  3. Selection(ListView)
  4. Expand/Collapse(ComboBox)

일치하는 항목이 식별되지 않으면 액셀러레이터가 유효하지 않고 디버그 메시지가 제공됩니다("이 구성 요소에 대한 자동화 패턴을 찾을 수 없습니다.) Invoked 이벤트에서 원하는 모든 동작을 구현합니다. 이벤트 처리기에서 Handled를 true로 설정하면 이 메시지가 표시되지 않습니다.")

사용자 지정 키보드 가속기 동작

KeyboardAccelerator 개체의 Invoked 이벤트는 가속기가 실행되면 시작됩니다. KeyboardAcceleratorInvokedEventArgs 이벤트 개체에는 다음 속성이 포함됩니다.

  • Handled(Boolean): 이 값을 true로 설정하면 컨트롤 패턴을 트리거하는 이벤트를 방지하고 가속기 이벤트 버블링을 중지합니다. 기본 설정은 거짓입니다.
  • Element(DependencyObject): 가속기와 연결된 개체입니다.
  • KeyboardAccelerator: Invoked 이벤트를 발생시키는 데 사용되는 키보드 가속기입니다

여기서는 ListView의 항목에 대한 키보드 가속기 컬렉션을 정의하는 방법과 각 가속기의 Invoked 이벤트를 처리하는 방법을 보여줍니다.

<ListView x:Name="MyListView">
  <ListView.KeyboardAccelerators>
    <KeyboardAccelerator Key="A" Modifiers="Control,Shift" Invoked="SelectAllInvoked" />
    <KeyboardAccelerator Key="F5" Invoked="RefreshInvoked"  />
  </ListView.KeyboardAccelerators>
</ListView>
void SelectAllInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
  MyListView.SelectAll();
  args.Handled = true;
}

void RefreshInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
  MyListView.SelectionMode = ListViewSelectionMode.None;
  MyListView.SelectionMode = ListViewSelectionMode.Multiple;
  args.Handled = true;
}

기본 키보드 동작 재정의

일부 컨트롤은 포커스가 있을 때 앱 정의 가속기를 재정의하는 기본 제공 키보드 가속기를 지원합니다. 예를 들어 TextBox에 포커스가 있을 때 Control+C 가속기는 현재 선택한 텍스트만 복사합니다(즉, 앱에서 정의한 가속기는 무시되고 다른 기능은 실행되지 않음).

사용자의 익숙함과 기대 때문에 기본 제어 동작을 재정의하지 않는 것이 좋지만, 컨트롤의 기본 제공 키보드 가속기를 재정의할 수 있습니다. 다음 예제에서는 PreviewKeyDown 이벤트 처리기를 통해 TextBox에 대한 Control+C 키보드 가속기를 재정의하는 방법을 보여줍니다.

 private void TextBlock_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
 {
    var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(Windows.System.VirtualKey.Control);
    var isCtrlDown = ctrlState == CoreVirtualKeyStates.Down || ctrlState 
        ==  (CoreVirtualKeyStates.Down | CoreVirtualKeyStates.Locked);
    if (isCtrlDown && e.Key == Windows.System.VirtualKey.C)
    {
        // Your custom keyboard accelerator behavior.
        
        e.Handled = true;
    }
 }

키보드 가속기 비활성화

컨트롤이 비활성화된 경우 연결된 가속기도 비활성화됩니다. 다음 예제에서는 ListView의 IsEnabled 속성이 false로 설정되어 있기 때문에 연결된 Control+A 가속기를 호출할 수 없습니다.

<ListView >
  <ListView.KeyboardAccelerators>
    <KeyboardAccelerator Key="A"
      Modifiers="Control"
      Invoked="CustomListViewSelecAllInvoked" />
  </ListView.KeyboardAccelerators>
  
  <TextBox>
    <TextBox.KeyboardAccelerators>
      <KeyboardAccelerator 
        Key="A" 
        Modifiers="Control" 
        Invoked="CustomTextSelecAllInvoked" 
        IsEnabled="False" />
    </TextBox.KeyboardAccelerators>
  </TextBox>

<ListView>

부모 및 자식 컨트롤은 동일한 가속기를 공유할 수 있습니다. 이 경우 자식 컨트롤에 포커스가 있고 가속기가 비활성화된 경우에도 부모 컨트롤을 호출할 수 있습니다.

화면 읽기 프로그램 및 키보드 가속기

내레이터와 같은 화면 읽기 프로그램은 키보드 가속기 키 조합을 사용자에게 알릴 수 있습니다. 기본적으로 각 보조 키(VirtualModifiers 열거형 순서) 다음에 키("+" 기호로 구분) 순서입니다. AcceleratorKey AutomationProperties 연결된 속성을 통해 사용자 지정할 수 있습니다. 둘 이상의 가속기가 지정되면 첫 번째 가속기만 알려집니다.

이 예제에서 AutomationProperty.AcceleratorKey는 "Control+Shift+A"라는 문자열을 반환합니다.

<ListView x:Name="MyListView">
  <ListView.KeyboardAccelerators>

    <KeyboardAccelerator 
      Key="A" 
      Modifiers="Control,Shift" 
      Invoked="CustomSelectAllInvoked" />
      
    <KeyboardAccelerator 
      Key="F5" 
      Modifiers="None" 
      Invoked="RefreshInvoked" />

  </ListView.KeyboardAccelerators>

</ListView>   

참고 항목

AutomationProperties.AcceleratorKey를 설정해도 키보드 기능이 활성화되지는 않으며 UIA 프레임워크에만 사용되는 키를 나타냅니다.

일반적인 키보드 가속기

Windows 애플리케이션 전체에서 키보드 가속기를 일관되게 만드는 것이 좋습니다.

사용자는 키보드 가속기를 기억해야 하고 동일한(또는 비슷한) 결과를 기대하지만, 앱 간의 기능 차이로 인해 이렇게 할 수 없는 경우도 있습니다.

편집 일반적인 키보드 가속기
편집 모드 시작 Ctrl + E
포커스가 설정된 컨트롤이나 창에 있는 모든 항목 선택 Ctrl + A
찾기 및 바꾸기 Ctrl+H
실행 취소 Ctrl + Z
다시 실행 Ctrl + Y
선택 항목을 삭제하고 클립보드에 복사 Ctrl + X
클립보드로 선택 영역 복사 Ctrl+C, Ctrl+Insert
클립보드의 내용 붙여넣기 Ctrl+V, Shift+Insert
클립보드의 콘텐츠 붙여 넣기(옵션 포함) Ctrl + Alt + V
항목 이름 바꾸기 F2
새 항목 추가 Ctrl+N
새 보조 항목 추가 Ctrl+Shift+N
선택한 항목 삭제(실행 취소 포함) Del, Ctrl+D
선택한 항목 삭제(실행 취소 불포함) Shift+Del
굵게 Ctrl + B
밑줄 Ctrl+U
Normal Ctrl+I
탐색
포커스가 설정된 컨트롤 또는 창에서 콘텐츠 찾기 Ctrl+F
다음 검색 결과로 이동 F3
기타 작업
즐겨찾기 추가 Ctrl+D
보충 F5 또는 Ctrl+R
확대 Ctrl++
축소 Ctrl+-
기본 보기로 확대/축소 Ctrl+0
저장 Ctrl+S
닫기 Ctrl + W
인쇄 Ctrl+P

일부 조합은 Windows의 지역화된 버전에 유효하지 않습니다. 예를 들어 스페인어 버전의 Windows에서는 '굵게'에 대해 Ctrl+N이 Ctrl+B 대신 사용됩니다. 앱이 지역화되어 있는 경우 지역화된 키보드 가속기를 제공하는 것이 좋습니다.

키보드 가속기의 유용성 기능

도구 설명

일반적으로 키보드 가속기는 Windows 애플리케이션의 UI에 직접 설명되어 있지는 않지만, 도구 설명을 통해 사용자에게 보다 잘 표시되도록 할 수 있습니다. 도구 설명은 사용자가 포커스를 이동하거나, 누르고 있거나, 마우스 포인터를 컨트롤 위로 이동하면 자동으로 표시됩니다. 도구 설명을 통해 컨트롤에 연결된 키보드 가속기가 있는지 확인할 수 있으며, 있는 경우 가속기 키 조합이 표시됩니다.

Windows 10 버전 1803(2018년 4월 업데이트) 이상

기본적으로 키보드 가속기를 선언하면 MenuFlyoutItemToggleMenuFlyoutItem을 제외한 모든 컨트롤이 해당하는 키 조합을 도구 설명에 표시합니다.

참고 항목

컨트롤의 가속기가 2개 이상 정의된 경우 첫 번째 가속기만 표시됩니다.

Screenshot of a Save button with a tool tip above it that indicates support for the Ctrl+S accelerator.
도구 설명의 가속기 키 콤보

Button, AppBarButtonAppBarToggleButton 개체의 경우 키보드 가속기가 컨트롤의 기본 도구 설명에 추가됩니다. MenuFlyoutItemToggleMenuFlyoutItem 개체의 경우 키보드 가속기가 플라이아웃 텍스트와 함께 표시됩니다.

참고 항목

도구 설명을 지정하면(다음 예제의 Button1 참조) 이 동작이 재정의됩니다.

<StackPanel x:Name="Container" Grid.Row="0" Background="AliceBlue">
    <Button Content="Button1" Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto" 
            ToolTipService.ToolTip="Tooltip">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="A" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
    <Button Content="Button2"  Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="B" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
    <Button Content="Button3"  Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="C" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
</StackPanel>

Screenshot of three buttons labeled Button1, Button2, and Button3 with a tool tip above Button2 that indicates support for the Windows+B accelerator.

Button의 기본 도구 설명에 가속기 키 조합이 추가됨

<AppBarButton Icon="Save" Label="Save">
    <AppBarButton.KeyboardAccelerators>
        <KeyboardAccelerator Key="S" Modifiers="Control"/>
    </AppBarButton.KeyboardAccelerators>
</AppBarButton>

Screenshot of a button with a Disk icon and a tool tip that includes the default Save text appended with the Ctrl+S accelerator in parentheses.

AppBarButton의 기본 도구 설명에 가속기 키 조합이 추가됨

<AppBarButton AccessKey="R" Icon="Refresh" Label="Refresh" IsAccessKeyScope="True">
    <AppBarButton.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem AccessKey="A" Icon="Refresh" Text="Refresh A">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator Key="R" Modifiers="Control"/>
                </MenuFlyoutItem.KeyboardAccelerators>
            </MenuFlyoutItem>
            <MenuFlyoutItem AccessKey="B" Icon="Globe" Text="Refresh B" />
            <MenuFlyoutItem AccessKey="C" Icon="Globe" Text="Refresh C" />
            <MenuFlyoutItem AccessKey="D" Icon="Globe" Text="Refresh D" />
            <ToggleMenuFlyoutItem AccessKey="E" Icon="Globe" Text="ToggleMe">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator Key="Q" Modifiers="Control"/>
                </MenuFlyoutItem.KeyboardAccelerators>
            </ToggleMenuFlyoutItem>
        </MenuFlyout>
    </AppBarButton.Flyout>
</AppBarButton>

Screenshot of a Menu with MenuFlyoutItems that include accelerator key combos.
MenuFlyoutItem의 텍스트에 추가된 가속기 키 콤보

KeyboardAcceleratorPlacementMode 속성(자동 또는 숨김의 두 값 허용)을 사용하면 표시 동작을 제어할 수 있습니다.

<Button Content="Save" Click="OnSave" KeyboardAcceleratorPlacementMode="Auto">
    <Button.KeyboardAccelerators>
        <KeyboardAccelerator Key="S" Modifiers="Control" />
    </Button.KeyboardAccelerators>
</Button>

경우에 따라 다른 요소(일반적으로 컨테이너 개체)를 기준으로 도구 설명을 표시해야 할 수 있습니다.

다음은 KeyboardAcceleratorPlacementTarget 속성을 사용하여 단추 대신 그리드 컨테이너를 사용하여 저장 단추에 대한 바로 가기 키 조합을 표시하는 방법입니다.

<Grid x:Name="Container" Padding="30">
  <Button Content="Save"
    Click="OnSave"
    KeyboardAcceleratorPlacementMode="Auto"
    KeyboardAcceleratorPlacementTarget="{x:Bind Container}">
    <Button.KeyboardAccelerators>
      <KeyboardAccelerator  Key="S" Modifiers="Control" />
    </Button.KeyboardAccelerators>
  </Button>
</Grid>

레이블

경우에 따라 컨트롤의 레이블을 사용하여 컨트롤에 연결된 바로 가기 키의 유무를 확인하고, 있는 경우 바로 가기 키가 무엇인지를 확인하는 것이 좋을 수 있습니다.

일부 플랫폼 컨트롤은 기본적으로 이러한 작업을 수행합니다(특히 MenuFlyoutItemToggleMenuFlyoutItem 개체). 반면, AppBarButtonAppBarToggleButtonCommandBar의 오버플로 메뉴에 표시될 때 이를 수행합니다.

Keyboard accelerators described in a menu item label.
메뉴 항목 레이블에 설명된 바로 가기 키

MenuFlyoutItem, ToggleMenuFlyoutItem, AppBarButtonAppBarToggleButton 컨트롤의 KeyboardAcceleratorTextOverride 속성을 통해 레이블의 기본 바로 가기 텍스트를 재정의할 수 있습니다(텍스트가 없는 경우 빈 칸 하나 사용).

참고 항목

시스템에서 연결된 키보드를 검색할 수 없는 경우 재정의 텍스트가 표시되지 않습니다(KeyboardPresent 속성을 통해 이를 자체적으로 확인할 수 있음).

고급 개념

여기서는 키보드 가속기의 몇 가지 하위 수준 측면을 검토합니다.

입력 이벤트 우선 순위

입력 이벤트는 앱의 요구 사항에 따라 가로채고 처리할 수 있는 특정 순서로 발생합니다.

KeyDown/KeyUp 버블링 이벤트

XAML에서는 입력 버블링 파이프라인이 하나만 있는 것처럼 키 입력이 처리됩니다. 이 입력 파이프 라인은 KeyDown/KeyUp 이벤트 및 문자 입력에 사용됩니다. 예를 들어 요소에 포커스가 있고 사용자가 키를 누른 경우 KeyDown 이벤트가 해당 요소 및 해당 요소의 부모 순서로 발생하며 args.Handled 속성이 true가 될 때까지 트리를 위로 이동합니다.

또한 KeyDown 이벤트는 일부 컨트롤에서 기본 제공 컨트롤 가속기를 구현하는 데 사용됩니다. 컨트롤에 키보드 가속기가 있으면 KeyDown 이벤트를 처리하므로 KeyDown 이벤트 버블링이 발생하지 않습니다. 예를 들어 RichEditBox는 Ctrl+C로 복사를 지원합니다. Ctrl을 누르면 KeyDown 이벤트가 시작되고 버블링이 발생하지만, 사용자가 동시에 C를 누르면 KeyDown 이벤트가 Handled로 표시되고 발생하지 않습니다(UIElement.AddHandler의 handledEventsToo 매개 변수가 true로 설정되지 않은 경우).

CharacterReceived 이벤트

CharacterReceived 이벤트는 TextBox와 같은 텍스트 컨트롤에 대한 KeyDown 이벤트 이후 실행되며, KeyDown 이벤트 처리기에서 문자 입력을 취소할 수 있습니다.

PreviewKeyDown 및 PreviewKeyUp 이벤트

미리 보기 입력 이벤트는 다른 이벤트보다 먼저 발생합니다. 이러한 이벤트를 처리하지 않으면 포커스가 있는 요소의 가속기가 실행된 후 KeyDown 이벤트가 발생합니다. 두 이벤트 모두 처리될 때까지 버블링됩니다.

Diagram showing the key event sequence키 이벤트 시퀀스

이벤트 순서:

Preview KeyDown 이벤트

앱 가속기
OnKeyDown 메서드
KeyDown 이벤트
부모의 앱 가속기
부모의 OnKeyDown 메서드
부모의 KeyDown 이벤트
(루트에 대한 Bubbles)

CharacterReceived 이벤트
PreviewKeyUp 이벤트
KeyUpEvents

가속기 이벤트가 처리되면 KeyDown 이벤트도 처리된 것으로 표시됩니다. KeyUp 이벤트는 처리되지 않은 상태로 유지됩니다.

가속기 해결

키보드 가속기 이벤트는 포커스가 있는 요소에서 루트까지 버블링합니다. 이벤트가 처리되지 않으면 XAML 프레임워크는 버블링 경로 외부의 다른 범위가 지정되지 않은 앱 가속기를 찾습니다.

두 개의 키보드 가속기가 동일한 키 조합으로 정의되면 시각적 트리에서 발견된 첫 번째 키보드 가속기가 호출됩니다.

범위가 지정된 키보드 가속기는 포커스가 특정 범위 안에 있는 경우에만 호출됩니다. 예를 들어 수십 개의 컨트롤이 포함된 Grid에서는 포커스가 Grid(범위 소유자) 내에 있는 경우에만 키보드 가속기를 컨트롤에 대해 호출할 수 있습니다.

프로그래밍 방식으로 가속기 범위 지정

UIElement.TryInvokeKeyboardAccelerator 메서드는 요소의 하위 트리에서 일치하는 모든 가속기를 호출합니다.

UIElement.OnProcessKeyboardAccelerators 메서드는 키보드 가속기보다 먼저 실행됩니다. 이 메서드는 키, 보조 키 및 키보드 가속기의 처리 여부를 나타내는 부울을 포함하는 ProcessKeyboardAcceleratorArgs를 전달합니다. 처리된 것으로 표시된 경우 키보드 가속기가 버블링됩니다(외부 키보드 가속기가 호출되지 않음).

참고 항목

OnProcessKeyboardAccelerators는 처리되든 처리되지 않든 항상 실행됩니다(OnKeyDown 이벤트와 유사함). 이벤트가 처리된 것으로 표시되었는지 확인해야 합니다.

이 예제에서는 OnProcessKeyboardAccelerators 및 TryInvokeKeyboardAccelerator를 사용하여 키보드 가속기를 Page 개체에 적용합니다.

protected override void OnProcessKeyboardAccelerators(
  ProcessKeyboardAcceleratorArgs args)
{
  if(args.Handled != true)
  {
    this.TryInvokeKeyboardAccelerator(args);
    args.Handled = true;
  }
}

가속기 지역화

모든 키보드 가속기를 지역화하는 것이 좋습니다. 이 작업은 XAML 선언의 표준 리소스(.resw) 파일과 x:Uid 특성을 사용하여 수행할 수 있습니다. 이 예에서 Windows 런타임은 자동으로 리소스를 로드합니다.

Diagram of keyboard accelerator localization with the resources file리소스 파일을 사용하여 키보드 가속기 지역화

<Button x:Uid="myButton" Click="OnSave">
  <Button.KeyboardAccelerators>
    <KeyboardAccelerator x:Uid="myKeyAccelerator" Modifiers="Control"/>
  </Button.KeyboardAccelerators>
</Button>

참고 항목

키보드 가속기는 가상 키로 구현됩니다. 지역화된 가속기는 미리 정의된 가상 키 코드 컬렉션에서 선택해야 합니다(그렇지 않으면 XAML 파서 오류가 발생).

프로그래밍 방식으로 가속기 설정

다음은 가속기를 프로그래밍 방식으로 정의하는 예제입니다.

void AddAccelerator(
  VirtualKeyModifiers keyModifiers, 
  VirtualKey key, 
  TypedEventHandler<KeyboardAccelerator, KeyboardAcceleratorInvokedEventArgs> handler )
  {
    var accelerator = 
      new KeyboardAccelerator() 
      { 
        Modifiers = keyModifiers, Key = key
      };
    accelerator.Invoked += handler;
    this.KeyboardAccelerators.Add(accelerator);
  }

참고 항목

KeyboardAccelerator는 공유할 수 없으며, 동일한 KeyboardAccelerator를 여러 요소에 추가할 수 없습니다.

키보드 가속기 동작 재정의

KeyboardAccelerator.Invoked 이벤트가 기본 KeyboardAccelerator 동작을 재정의하도록 처리할 수 있습니다.

다음은 사용자 지정 ListView 컨트롤에서 "모두 선택" 명령(Ctrl+A 바로 가기 키)을 재정의하는 방법을 보여주는 예입니다. 여기서는 또한 이벤트 버블링이 추가로 발생하지 않도록 Handled 속성을 true로 설정했습니다.

public class MyListView : ListView
{
  …
  protected override void OnKeyboardAcceleratorInvoked(KeyboardAcceleratorInvokedEventArgs args) 
  {
    if(args.Accelerator.Key == VirtualKey.A 
      && args.Accelerator.Modifiers == KeyboardModifiers.Control)
    {
      CustomSelectAll(TypeOfSelection.OnlyNumbers); 
      args.Handled = true;
    }
  }
  …
}

샘플