Поделиться через


Клавиатурные ускорители

Изображение героя клавиатуры Surface

Клавиши акселератора (или акселераторы клавиатуры) — это сочетания клавиш, которые повышают удобство использования и специальные возможности приложений, предоставляя пользователям интуитивно понятный способ вызова распространенных действий или команд без перехода к пользовательскому интерфейсу приложения.

Замечание

Клавиатура является незаменимой для пользователей с определенными ограниченными возможностями (см. специальные возможности клавиатуры), а также является важным инструментом для пользователей, которые предпочитают использовать его в качестве более эффективного способа взаимодействия с приложением.

Дополнительные сведения о навигации пользовательского интерфейса приложения Windows с помощью сочетаний клавиш см. в разделе "Ключи доступа ".

Сведения о создании собственных настраиваемых сочетаний клавиш см. в разделе "События клавиатуры ".

Обзор

Ускорители состоят из двух типов ключей: модификаторов и немодификаторов. Клавиши-модификаторы включают Shift, Menu, Control и клавишу Windows, которые предоставляются с помощью VirtualKeyModifiers. Не модификаторы включают любые виртуальные ключи, такие как Delete, F3, ПРОБЕЛ, СТРЕЛКА, ESC и все буквенно-цифровые и пунктуационные ключи.

Замечание

Акселераторы обычно включают клавиши функции F1–F12 или некоторые сочетания стандартного ключа, сопряженного с одним или несколькими клавишами-модификаторами (CTRL, SHIFT). Например, если пользователь нажимает клавиши CTRL+SHIFT+M, платформа проверяет модификаторы (CTRL и SHIFT) и запускает ускоритель, если он существует.

Многие элементы управления XAML имеют встроенные ускорители клавиатуры. Например, ListView поддерживает ctrl+A для выбора всех элементов в списке, а RichEditBox поддерживает сочетание клавиш CTRL+TAB для вставки вкладки в текстовое поле. Эти встроенные ускорители клавиатуры называются акселераторами управления и выполняются только в том случае, если фокус находится на элементе или одном из его дочерних элементов. Ускорители, определенные с помощью API акселератора клавиатуры, которые рассматриваются здесь, называются акселераторами приложений.

Ускорители клавиатуры недоступны для каждого действия, но часто связаны с командами, предоставляемыми в меню (и должны быть указаны с содержимым элемента меню). Ускорители также могут быть связаны с действиями, которые не имеют эквивалентных элементов меню. Тем не менее, поскольку пользователи используют меню приложения для обнаружения и изучения доступного набора команд, следует попытаться сделать обнаружение акселераторов как можно проще (с помощью меток или установленных шаблонов может помочь в этом).

Акселератор автоматически повторяется (например, когда пользователь нажимает клавиши Ctrl+Shift, а затем удерживает клавишу M, акселератор вызывается повторно, пока клавиша M не будет отпущена). Это поведение нельзя изменить.

Снимок экрана: акселераторы клавиатуры в метке элемента меню.
Ускорители клавиатуры, описанные в метке элемента меню

Когда следует использовать акселераторы клавиатуры

Рекомендуется указывать акселераторы клавиатуры в любом месте в пользовательском интерфейсе и поддерживать акселераторы во всех пользовательских элементах управления.

  • Ускорители клавиатуры делают приложение более доступным для пользователей с ограниченными возможностями двигателя, включая тех пользователей, которые могут нажать только один ключ за раз или иметь трудности с помощью мыши.

    Хорошо разработанный пользовательский интерфейс клавиатуры является важным аспектом доступности программного обеспечения. Он позволяет пользователям с нарушениями зрения или с определенными нарушениями двигателя перемещаться по приложению и взаимодействовать с его функциями. Такие пользователи могут не работать с мышью и вместо этого полагаться на различные вспомогательные технологии, такие как средства улучшения клавиатуры, экранные клавиатуры, расширения экрана, средства чтения с экрана и служебные программы ввода голоса. Для этих пользователей решающее значение имеет всестороннее покрытие команд.

  • Акселераторы клавиатуры делают приложение более пригодным для пользователей, которые предпочитают взаимодействовать с клавиатурой.

    Опытные пользователи часто имеют сильное предпочтение использовать клавиатуру, так как команды на основе клавиатуры могут быть введены быстрее и не требуют от них удаления рук с клавиатуры. Для этих пользователей эффективность и согласованность имеют решающее значение; комплексность важна только для наиболее часто используемых команд.

Указание акселератора клавиатуры

Используйте API KeyboardAccelerator для создания акселераторов клавиатуры в приложениях Windows. С помощью этих API вам не нужно обрабатывать несколько событий KeyDown для обнаружения сочетания клавиш, нажатых, и вы можете локализовать акселераторы в ресурсах приложения.

Рекомендуется задать акселераторы клавиатуры для наиболее распространенных действий в приложении и задокументировать их с помощью метки элемента меню или подсказки. В этом примере мы объявляем акселераторы клавиатуры только для команд "Переименовать" и "Копировать".

<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>

Снимок экрана: акселератор клавиатуры в подсказке.
Ускоритель клавиатуры, описанный в подсказке

Объект UIElement имеет коллекцию KeyboardAccelerator , KeyboardAccelerator, где вы указываете пользовательские объекты KeyboardAccelerator и определяете нажатия клавиш для акселератора клавиатуры:

Замечание

Поддерживаются ускорители с одним ключом (A, Delete, F2, Пробел, Esc, Мультимедиа Key) и акселераторы с несколькими ключами (CTRL+SHIFT+M). Однако виртуальные ключи Gamepad не поддерживаются.

Акселераторы с ограниченной областью

Некоторые акселераторы работают только в определенных областях, а другие работают на уровне приложения.

Например, 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>

Атрибут ScopeOwner элемента MenuFlyoutItem.KeyboardAccelerators помечает акселератор как ограниченный, а не глобальный (по умолчанию оно равно NULL, то есть глобально). Дополнительные сведения см. в разделе "Разрешение акселераторов" далее в этом материале.

Вызов акселератора клавиатуры

Объект KeyboardAccelerator использует шаблон управления автоматизации пользовательского интерфейса (UIA) для выполнения действий при вызове акселератора.

UIA [шаблоны элементов управления] предоставляют общие функции управления. Например, элемент управления Button реализует шаблон элемента управления Invoke для поддержки события Click (обычно элемент управления вызывается путем щелчка, двойного щелчка или нажатия клавиши ВВОД, предопределенного сочетания клавиш или другого сочетания нажатий клавиш). Если ускоритель клавиатуры используется для вызова элемента управления, платформа XAML ищет, реализует ли элемент управления шаблон элемента управления Invoke и, если да, активирует его (не требуется прослушивать событие KeyboardAcceleratorInvoked).

В следующем примере Control+S активирует событие Click, так как кнопка реализует шаблон Invoke.

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

Если элемент реализует несколько шаблонов элементов управления, его можно активировать только с помощью акселератора. Шаблоны элементов управления расставлены по приоритетам следующим образом:

  1. Вызов (кнопка)
  2. Переключатель (флажок)
  3. Выбор (ListView)
  4. Развернуть или свернуть (ComboBox)

Если совпадение не определено, акселератор недопустим, а отладочное сообщение предоставляется ("Шаблоны автоматизации для этого компонента не найдены. Реализуйте все требуемое поведение в событии "Вызываемый". Параметр Handled to true в обработчике событий подавляет это сообщение.")

Пользовательское поведение акселератора клавиатуры

Вызываемое событие объекта KeyboardAccelerator запускается при выполнении акселератора. Объект событий KeyboardAcceleratorInvokedEventArgs включает следующие свойства:

  • Обработано (логическое значение): если задано значение true, событие блокирует активацию шаблона элемента управления и останавливает бублинг события акселератора. Значение по умолчанию — false.
  • Элемент (DependencyObject): объект, связанный с акселератором.
  • KeyboardAccelerator: ускоритель клавиатуры, используемый для вызова события.

Здесь мы покажем, как определить коллекцию акселераторов клавиатуры для элементов в 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 копирует только выбранный текст (определяемые приложением акселераторы игнорируются и другие функции не выполняются).

Хотя мы не рекомендуем изменять поведение элементов управления по умолчанию из-за знакомости и ожиданий пользователей, вы можете переопределить встроенное клавиатурное ускорение элемента управления. В следующем примере показано, как переопределить ускоритель клавиатуры Control+C для TextBox с помощью обработчика событий PreviewKeyDown :

 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;
    }
 }

Отключение акселератора клавиатуры

Если элемент управления отключен, связанный акселератор также отключен. В следующем примере, поскольку свойство IsEnabled объекта ListView имеет значение 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
Bold CTRL+B
Подчеркивание CTRL+U
Курсив CTRL+I
Навигация
Поиск содержимого в фокусном элементе управления или окне CTRL+F
Перейдите к следующему результату поиска F3
Перейдите к следующей области пользовательского интерфейса F6
Перейдите к предыдущей области пользовательского интерфейса SHIFT +F6
Другие действия
Добавление избранного CTRL+D
Обновить F5 или CTRL+R
Увеличить Ctrl + +
Уменьшение масштаба Ctrl+-
Масштабирование до представления по умолчанию CTRL+0
Сохранить CTRL+S
Close CTRL+W
Print CTRL+P

Обратите внимание, что некоторые сочетания недопустимы для локализованных версий Windows. Например, в испанской версии Windows ctrl+N используется для полужирного шрифта вместо CTRL+B. Рекомендуется предоставлять локализованные акселераторы клавиатуры, если приложение локализовано.

Возможности использования для акселераторов клавиатуры

Подсказки

Поскольку ускорители клавиатуры обычно не описываются непосредственно в пользовательском интерфейсе приложения Windows, вы можете улучшить обнаружение с помощью подсказок, которые отображаются автоматически при перемещении фокуса, нажатии и удержании или наведении указателя мыши на элемент управления. Подсказка может определить, имеет ли элемент управления связанный акселератор клавиатуры и, если да, то что такое сочетание клавиш акселератора.

Windows 10 версии 1803 (обновление за апрель 2018 г.) и более поздние версии

По умолчанию при объявлении акселераторов клавиатуры все элементы управления (кроме MenuFlyoutItem и ToggleMenuFlyoutItem) представляют соответствующие сочетания клавиш в подсказке.

Замечание

Если элемент управления имеет несколько акселераторов, будет представлен только первый.

Снимок экрана кнопки
Комбинация клавиш акселератора в подсказке

Для объектов Button, AppBarButton и AppBarToggleButton акселератор клавиатуры добавляется в подсказку по умолчанию контрола. Для объектов MenuFlyoutItem и ToggleMenuFlyoutItem ускоритель клавиатуры отображается с текстом всплывающего элемента.

Замечание

Указание подсказки (см. 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>

Снимок экрана: три кнопки с меткой Button1, Button2 и Button3 с подсказкой над кнопкой 2, которая указывает на поддержку акселератора Windows+B.

Ключевая комбинация акселератора добавлена в подсказку по умолчанию кнопки

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

Снимок экрана: кнопка с значком диска и подсказкой инструмента, включающая текст по умолчанию, добавленный с помощью акселератора CTRL+S в скобках.

Комбинация клавиш акселератора добавлена в стандартную подсказку для 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>

Снимок экрана: меню с MenuFlyoutItems, включая сочетания клавиш-ускорителей.
К тексту MenuFlyoutItem добавлены сочетания клавиш-ускорителей.

Управление поведением презентации с помощью свойства KeyboardAcceleratorPlacementMode , которое принимает два значения: auto или Hidden.

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

В некоторых случаях может потребоваться представить подсказку относительно другого элемента (обычно объект контейнера).

Здесь показано, как использовать свойство KeyboardAcceleratorPlacementTarget для отображения комбинации клавиш ускорителя клавиатуры для кнопки "Сохранить" в контейнере Grid, а не на самой кнопке.

<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>

Наклейки

В некоторых случаях рекомендуется использовать метку элемента управления, чтобы определить, имеет ли элемент управления связанный акселератор клавиатуры и, если да, то что такое сочетание клавиш акселератора.

Некоторые элементы управления платформой делают это по умолчанию, в частности объекты MenuFlyoutItem и ToggleMenuFlyoutItem, а AppBarButton и AppBarToggleButton делают это, когда они отображаются в меню переполнения CommandBar.

Ускорители клавиатуры, описанные в метке элемента меню.
Ускорители клавиатуры, описанные в метке элемента меню

Текст акселератора по умолчанию можно переопределить с помощью свойства KeyboardAcceleratorTextOverride элемента управления MenuFlyoutItem, ToggleMenuFlyoutItem, AppBarButton и AppBarToggleButton (используйте одно пространство без текста).

Замечание

Текст переопределения не отображается, если система не может обнаружить подключенную клавиатуру (вы можете проверить это самостоятельно с помощью свойства KeyboardPresent ).

Расширенные понятия

Здесь мы рассмотрим некоторые низкоуровневые аспекты акселераторов клавиатуры.

Приоритет события ввода

События ввода происходят в определенной последовательности, которую можно перехватывать и обрабатывать на основе требований приложения.

Событие "KeyDown/KeyUp"

В XAML нажатие клавиш обрабатывается так, как если бы было только одно всплытие событий ввода. Этот входной конвейер используется событиями KeyDown/KeyUp и символьным вводом. Например, если элемент имеет фокус и пользователь нажимает клавишу, событие KeyDown вызывается на этом элементе, затем на его родительском элементе и так далее вверх по иерархии, пока свойство args.Handled не станет истинным.

Событие KeyDown также используется некоторыми контролами для реализации встроенных акселераторов управления. Если элемент управления имеет ускоритель клавиатуры, он обрабатывает событие KeyDown, что означает, что событие KeyDown не будет бурным. Например, RichEditBox поддерживает копирование с помощью CTRL+C. При удерживании клавиши Ctrl событие KeyDown запускается и распространяется, но когда пользователь одновременно нажимает C, событие KeyDown помечается как Обработано и не вызывается (если параметр handledEventsToo UIElement.AddHandler имеет значение true).

Событие "CharacterReceived"

Так как событие CharacterReceived запускается после события KeyDown для текстовых элементов управления, таких как TextBox, можно отменить входные данные символов в обработчике событий KeyDown.

События PreviewKeyDown и PreviewKeyUp

События предварительного просмотра запускаются перед любыми другими событиями. Если вы не обрабатываете эти события, акселератор для элемента с фокусом запускается, а затем событие KeyDown. Оба события будут распространяться до обработки.

Схема, показывающая ключевую последовательность событий Ключевая последовательность событий

Порядок событий:

Предварительный просмотр событий KeyDown

Акселератор приложений
Метод OnKeyDown
Событие KeyDown
Акселераторы приложений в родительской системе
Метод OnKeyDown на родительском элементе
Событие KeyDown в родительском элементе
(Пузырьки к корням)

Событие CharacterReceived
События PreviewKeyUp
KeyUpEvents

Когда событие акселератора обрабатывается, событие KeyDown также отмечается как обработанное. Событие KeyUp остается необработанным.

Разрешение акселераторов

Событие акселератора клавиатуры распространяется от элемента, на котором установлен фокус, до корня. Если событие не обрабатывается, платформа XAML ищет другие акселераторы приложений вне области видимости вне текущего пути.

При определении двух акселераторов клавиатуры с одинаковым сочетанием клавиш вызывается первый ускоритель клавиатуры, найденный в визуальном дереве.

Ускорители клавиатуры с областью действия вызываются только в том случае, если фокус находится внутри определенной области. Например, в сетке, содержащей десятки элементов управления, ускоритель клавиатуры можно вызывать только в том случае, если фокус находится в сетке (владелец области).

Программное определение области действия акселераторов

Метод UIElement.TryInvokeKeyboardAccelerator вызывает все соответствующие ускорители в поддереве элемента.

Метод UIElement.OnProcessKeyboardAccelerator выполняется перед акселератором клавиатуры. Этот метод передает объект ProcessKeyboardAcceleratorArgs , содержащий ключ, модификатор и логическое значение, указывающее, обрабатывается ли ускоритель клавиатуры. Если отмечено как обработанное, пузырьки акселератора клавиатуры (поэтому внешний ускоритель клавиатуры никогда не вызывается).

Замечание

OnProcessKeyboardAccelerator всегда запускается независимо от того, обрабатывается или нет (аналогично событию OnKeyDown). Необходимо проверить, помечено ли событие как обработанное.

В этом примере мы используем OnProcessKeyboardAccelerator и TryInvokeKeyboardAccelerator для ограничения области действия акселераторов клавиатуры на объекте Page.

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

Локализация акселераторов

Рекомендуется локализовать все акселераторы клавиатуры. Это можно сделать с помощью стандартного файла ресурсов (.resw) и атрибута x:Uid в объявлениях XAML. В этом примере среда выполнения Windows автоматически загружает ресурсы.

Схема локализации акселератора клавиатуры с помощью файла ресурсов Локализация акселератора клавиатуры с помощью файла ресурсов

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

Замечание

Ускорители клавиатуры реализуются как виртуальные ключи. Локализованные акселераторы должны быть выбраны из предопределенной коллекции кодовVirtual-Key (в противном случае возникнет ошибка средства синтаксического анализа 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 по умолчанию.

В этом примере показано, как переопределить команду "Выбрать все" (клавиатурный акселератор Ctrl+A) в пользовательском элементе управления ListView. Мы также задаем свойству 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;
    }
  }
  …
}

Samples