共用方式為


鍵盤快速操作

Surface 鍵盤的主圖影像

對應鍵 (或鍵盤對應鍵) 是鍵盤快速鍵,透過為使用者提供一種直覺的方法來呼叫常見動作或命令而不必瀏覽應用程式 UI,從而提高 Windows 應用程式的可用性和協助效果。

注意

對於具有某些殘疾的使用者來說,鍵盤不可或缺 (請參閱鍵盤協助工具),對於偏好使用鍵盤的使用者來說,鍵盤也是用來與應用程式更有效率互動的重要工具。

如需使用鍵盤快速鍵瀏覽 Windows 應用程式 UI 的詳細資料,請參閱便捷鍵主題。

若要建立自己的自訂鍵盤快速鍵,請參閱鍵盤事件主題。

概觀

對應鍵是由兩種類型的索引鍵所組成:輔助按鍵和非輔助按鍵。 輔助按鍵包括 Shift、Menu、Control 和 Windows 鍵,這些按鍵是透過 VirtualKeyModifiers 公開的。 非輔助按鍵包含任何 VirtualKey,例如 Delete、F3、空格鍵、方向鍵、Esc,以及所有英數字元和標點符號按鍵。

注意

對應鍵通常包含函式按鍵 F1 到 F12 或標準按鍵組合的一些組合,以及一或多個輔助按鍵 (CTRL、Shift)。 例如,如果使用者按下 Ctrl+Shift+M,架構將檢查輔助按鍵 (Ctrl 和 Shift),並觸發對應鍵 (如果存在)。

許多 XAML 控制項都有內建的鍵盤對應鍵。 例如,ListView 支援 Ctrl+A 來選取清單中的所有項目,RichEditBox 支援 Ctrl+Tab 以在文字方塊中插入 Tab。 這些內建鍵盤對應鍵稱為控制對應鍵,只有當焦點位於元素或其子元素上時才會執行。 使用此處討論的鍵盤對應鍵 API 定義的對應鍵稱為應用程式對應鍵

鍵盤對應鍵不適用於每個動作,但通常與功能表公開的命令相關聯 (且應該使用功能表項內容指定)。 對應鍵也可以與沒有等效功能表項目的動作相關聯。 但是,由於使用者依賴應用程式的功能表來探索和了解可用的命令集,因此應盡量輕鬆地探索對應鍵 (使用標籤或已建立的模式可以協助執行此動作)。

對應鍵自動重複 (例如,當使用者按下 Ctrl+Shift,然後按住 M 時,會重複叫用對應鍵,直到放開 M 為止)。 無法修改這個行為。

功能表項標籤中鍵盤快捷方式的螢幕快照。
功能表項目標籤中所述的鍵盤對應鍵

使用鍵盤對應鍵的時機

建議在 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>

工具提示中鍵盤快捷方式的螢幕快照。
工具提示中所述的鍵盤對應鍵

UIElement 物件具有 KeyboardAccelerator 集合 (KeyboardAccelerators),可在其中指定自訂 KeyboardAccelerator 物件並定義鍵盤對應鍵的按鍵:

注意

支持按鍵 (A、Delete、F2、Spacebar、Esc、Multimedia 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>

MenuFlyoutItem.KeyboardAccelerators 元素的 ScopeOwner 屬性會將快速鍵標示為已限定範圍,而不是全域範圍 (預設值為 Null 或 global)。 如需詳細資訊,請參閱本主題後面部分的解析對應鍵一節。

叫用鍵盤對應鍵

KeyboardAccelerator 物件會使用 UI 自動化 (UIA) 控制項模式在叫用對應鍵時採取動作。

UIA [控制項模式] 會公開常見的控制功能。 例如,Button 控制項會實作 Invoke 控制項模式以支援 Click 事件 (通常是藉由按一下、連按兩下或按 Enter、預先定義的鍵盤快速鍵,或其他按鍵組合來叫用控制項)。 使用鍵盤對應鍵叫用控制項時,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. 展開/摺疊 (下拉式方塊)

如果未找到任何符合項目,則對應鍵會無效,並且提供偵錯訊息 (「找不到此元件的自動化模式。在叫用事件中實現所有所需行為。在事件處理常式中將 Handled 設為 true 會隱藏顯示此訊息。」)

自訂鍵盤對應鍵行為

執行對應鍵時,會觸發 KeyboardAccelerator 物件的叫用事件。 KeyboardAcceleratorInvokedEventArgs 事件物件包含以下屬性:

  • Handled (布林值):將其設定為 true 可防止事件觸發控制項模式,並停止對應鍵事件反昇。 預設值為 false。
  • Element (DependencyObject):與對應鍵相關聯的物件。
  • KeyboardAccelerator:用來引發叫用事件的鍵盤對應鍵。

我們在這裡示範如何定義 ListView 中項目的鍵盤對應鍵集合,以及如何處理每個對應鍵的叫用事件。

<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 獲得焦點時,Ctrl+C 對應鍵僅複製目前選取的文字 (忽略應用程式定義快速鍵且不執行其他功能)。

我們不建議因為使用者的熟悉程度和期望而覆寫預設控制行為,但您可以覆寫控制項的內建鍵盤對應鍵。 以下範例示範如何透過 PreviewKeyDown 事件處理常式覆寫 TextBox 的 Ctrl+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
Italic Ctrl + I
導覽
在具有焦點的控制項或 Window 中尋找內容 Ctrl+F
移至下一個搜尋結果 F3
移至下一個 UI 窗格 F6
移至上一個UI窗格 Shift + F6
其他動作
新增我的最愛 Ctrl + D
Refresh 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 以外) 都會在工具提示中顯示對應的按鍵組合。

注意

如果控制項已定義多個對應鍵,則只會顯示第一個對應鍵。

[儲存] 按鈕的螢幕快照,其上方有工具提示,指出 Ctrl+S 快捷鍵的支援。
工具提示中的對應鍵組合

對於 ButtonAppBarButtonAppBarToggleButton 物件,鍵盤對應鍵會附加至控制項的預設工具提示。 對於 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>

標示為 Button1、Button2 和 Button3 的三個按鈕螢幕快照,其工具提示高於 Button2,表示支援 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 屬性控制呈現行為,此屬性接受兩個值:AutoHidden

<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 物件,而 AppBarButtonAppBarToggleButton 會在 CommandBar 溢位功能表中顯示時執行此動作。

功能表項標籤中所述的鍵盤快捷鍵。
功能表項目標籤中所述的鍵盤對應鍵

可以透過 MenuFlyoutItemToggleMenuFlyoutItemAppBarButtonAppBarToggleButton 控制項的 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 事件

對於文字控制項 (例如:TextBox),由於CharacterReceived 事件是在 KeyDown 事件之後觸發,因此您可以在 KeyDown 事件處理常式中取消字元輸入。

PreviewKeyDown 和 PreviewKeyUp 事件

預覽輸入事件會在任何其他事件之前觸發。 如果不處理這些事件,則會觸發具有焦點的元素之對應鍵,然後接著觸發 KeyDown 事件。 這兩個事件在處理前會都會反昇。

顯示索引鍵事件順序的圖表按鍵事件順序

事件順序:

預覽 KeyDown 事件
 
應用程式對應鍵
OnKeyDown 方法
KeyDown 事件
父系上的應用程式對應鍵
父系上的 OnKeyDown 方法
父系上的 KeyDown 事件
(反昇到根)
 
CharacterReceived 事件
PreviewKeyUp 事件
KeyUpEvents

處理對應鍵事件時,KeyDown 事件也會標示為已處理。 KeyUp 事件仍然未處理。

解析對應鍵

鍵盤對應鍵事件會從具有焦點的元素反昇至根。 如果未處理該事件,XAML 架構將在反昇路徑之外尋找其他不限範圍的應用程式對應鍵。

使用相同按鍵組合定義兩個鍵盤對應鍵時,會叫用可視化樹狀結構上找到的第一個鍵盤對應鍵。

只有在焦點位於特定範圍內時,才會叫用限定範圍的鍵盤對應鍵。 例如,在包含數十個控制項的網格中,只有在焦點位於網格內 (範圍擁有者) 時,才能為控制項叫用鍵盤對應鍵。

以程式設計方式限定對應鍵的範圍

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

將對應鍵當地語系化

建議將所有鍵盤對應鍵當地語系化。 可以使用標準資源 (.resw) 檔案和 XAML 宣告中的 x:Uid 屬性來執行此動作。 在此範例中,Windows 執行階段會自動載入資源。

使用資源檔案進行鍵盤快捷鍵本地化的圖表使用資源檔案進行鍵盤快速鍵當地語系化

<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 控制項中覆寫「Select all」命令 (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;
    }
  }
  …
}

範例