鍵盤協助工具

在應用程式中建置鍵盤輔助功能(適用於傳統、修改或鍵盤模擬硬體),可讓使用者失明、視力低、運動障礙或手部很少或無用,能夠流覽及使用應用程式的完整功能。 此外,沒有殘疾的使用者可能會因為喜好設定或效率而選擇鍵盤進行流覽。

如果您的應用程式未提供良好的鍵盤存取,則盲人或行動問題的使用者可能很難使用您的應用程式。

UI 元素之間的鍵盤瀏覽

若要使用鍵盤與控件互動,控件必須具有焦點。 若要接收焦點(不使用指標),控件必須可透過索引標籤覽來存取。 根據預設,控件的定位順序與它們新增至設計介面的順序相同、在 XAML 中宣告,或以程式設計方式新增至容器。

一般而言,預設定位順序是以 XAML 中定義控件的方式為基礎,特別是螢幕助讀程式周遊控件的順序。 不過,預設順序不一定對應至視覺順序。 實際顯示位置可能取決於父版面配置容器,以及可能會影響配置之子元素的各種屬性。

為了確保您的應用程式有最佳的定位順序,請自行測試行為。 如果您使用網格線或表格進行版面配置,則使用者讀取畫面的順序與定位順序可能會大不相同。 這不一定是個問題,但只要確定透過觸控和鍵盤測試應用程式的功能,以確認您的 UI 已針對這兩種輸入方法優化。

您可以藉由調整 XAML 或覆寫預設定位順序,使定位順序符合視覺順序。 下列範例示範如何使用 TabIndex 屬性搭配使用使用數據行優先索引標籤導覽的 Grid 配置。

<Grid>
  <Grid.RowDefinitions>...</Grid.RowDefinitions>
  <Grid.ColumnDefinitions>...</Grid.ColumnDefinitions>

  <TextBlock Grid.Column="1" HorizontalAlignment="Center">Groom</TextBlock>
  <TextBlock Grid.Column="2" HorizontalAlignment="Center">Bride</TextBlock>

  <TextBlock Grid.Row="1">First name</TextBlock>
  <TextBox x:Name="GroomFirstName" Grid.Row="1" Grid.Column="1" TabIndex="1"/>
  <TextBox x:Name="BrideFirstName" Grid.Row="1" Grid.Column="2" TabIndex="3"/>

  <TextBlock Grid.Row="2">Last name</TextBlock>
  <TextBox x:Name="GroomLastName" Grid.Row="2" Grid.Column="1" TabIndex="2"/>
  <TextBox x:Name="BrideLastName" Grid.Row="2" Grid.Column="2" TabIndex="4"/>
</Grid>

在某些情況下,您可能會想要從定位順序中排除特定控件。 這通常是藉由將控件的 IsEnabled 屬性設定為 false 來完成。 已停用的控制項會自動從定位順序中排除。

如果您想要從定位順序排除互動式控件,您可以將IsTabStop屬性設定false。

根據預設,支援焦點的UI元素通常會包含在定位順序中。 有些例外狀況包括支援文字選取和剪貼簿存取焦點的特定文字顯示類型(例如 RichTextBlock),但不是定位順序,因為它們是靜態文字元素。 這些控件不是傳統的互動式控件(無法叫用,而且不需要文字輸入,但確實支援文字控制樣式模式,可支援尋找和調整文字中的選取點)。 文字控件仍會由輔助技術偵測,並在螢幕助讀程式中大聲朗讀,但依賴定位順序以外的技術。

無論您選擇調整 TabIndex 值或使用預設順序,以下規則都適用:

  • 如果未在元素上設定 TabIndex,預設值為 Int32.MaxValue,而定位順序是以 XAML 或子集合中的宣告順序為基礎。
  • 如果在元素上設定了 TabIndex
    • TabIndex 等於 0 的 UI 元素會根據其在 XAML 或子集合中的宣告順序,新增至定位順序。
    • TabIndex 大於 0 的 UI 元素會根據 TabIndex 值,新增至定位順序。
    • TabIndex 小於 0 的 UI 元素會新增至定位順序,並顯示在任何零值之前。

下列代碼段顯示具有各種 TabIndex 設定的專案集合(B已指派 Int32.MaxValue 的值,或 2,147,483,647)。

<StackPanel Background="#333">
  <StackPanel Background="#FF33FF">
    <Button>A</Button>
    <Button TabIndex="2147483647">B</Button>
    <Button>C</Button>
  </StackPanel>
  <StackPanel Background="#33FFFF">
    <Button TabIndex="1">D</Button>
    <Button TabIndex="1">E</Button>
    <Button TabIndex="0">F</Button>
  </StackPanel>
</StackPanel>

這會產生以下定位順序:

  1. F
  2. D
  3. E
  4. A
  5. B
  6. C

使用 F6 的應用程式窗格之間的鍵盤流覽

應用程式窗格是應用程式視窗內突出相關UI的邏輯區域(例如,Microsoft Edge 窗格包括網址列、書籤列、索引卷標列和內容面板)。 F6 鍵可用來在這些窗格之間巡覽,然後可以使用標準鍵盤瀏覽來存取子元素群組。

雖然鍵盤流覽可以提供符合存取規範的UI,但讓可存取的UI通常需要更多步驟。 通常,這包括:

  • 聆聽 F6 以在 UI 的重要區段之間巡覽。
  • UI中新增常見動作的 鍵盤快捷方式。
  • 將訪問鍵新增至UI中的重要控制件。

如需實作快捷方式和訪問鍵的詳細資訊,請參閱下方的鍵盤快捷方式和訪問鍵。

優化 F6

F6 可讓鍵盤使用者在UI窗格之間有效率地巡覽,而不需要按索引標籤覽數百個控制件。

例如,Microsoft Edge 中的 F6 會在網址列、書籤列、索引卷標列和內容面板之間迴圈。 由於網頁可能會有數百個可索引標籤控件,F6 可讓鍵盤使用者更輕鬆地連線到索引標籤和網址列,而不需要使用應用程式特定的快捷方式。

F6 索引標籤週期也可以鬆散地對應到 內容中的地標或標題 ,不過它不需要完全相符。 F6 應該將焦點放在UI中的大型相異區域,而地標可能會更細微。 例如,您可以將應用程式行及其搜尋方塊標示為地標,但只會在 F6 迴圈中包含應用程式行本身。

重要

您必須在應用程式中實作 F6 導覽,因為它原本就不受支援。

可能的話,F6 迴圈中的區域應該具有可存取的名稱:透過地標或手動將 AutomationProperties.Name 新增至區域的「根」元素。

Shift-F6 應該以相反的方向迴圈。

UI 元素內部的鍵盤導覽

對於複合控件,請務必確保自主元素之間的正確內部流覽。 複合控件可以管理目前作用中的子專案,以減少讓所有子元素都支援焦點的額外負荷。 複合控件包含在定位順序中,並處理鍵盤導覽事件本身。 許多複合控件已經在其事件處理中建置了一些內部導覽邏輯。 例如,使用方向鍵周遊項目的功能會在 ListViewGridViewListBoxFlipView 控制項上預設啟用。

特定控制項元素之遊標動作和事件的鍵盤替代方案

可以按兩下的UI元素也應該透過鍵盤叫用。 若要搭配UI元素使用鍵盤,元素必須具有焦點(只有衍生自 控件 的類別支援焦點和索引標籤覽)。

針對可叫用的 UI 元素,請為空白鍵和 Enter 鍵實作鍵盤事件處理常式。 這可確保基本的鍵盤輔助功能支援,並讓使用者只使用鍵盤連線到所有互動式UI元素並啟用功能。

如果元素不支援焦點,您可以建立自己的自定義控件。 在此情況下,若要啟用焦點,您必須將IsTabStop屬性設定true,而且您必須以焦點指標提供焦點視覺狀態的視覺指示。

不過,使用控件組合會比較容易,以便支持製表位、焦點和Microsoft 使用者介面自動化對等和模式,由您選擇要撰寫內容的控件處理。 例如,不要在 Image處理按下指標的事件,而是將該元素包裝在 Button以取得指標、鍵盤和焦點支援。

<!--Don't do this.-->
<Image Source="sample.jpg" PointerPressed="Image_PointerPressed"/>

<!--Do this instead.-->
<Button Click="Button_Click"><Image Source="sample.jpg"/></Button>

鍵盤快速鍵

除了實作鍵盤瀏覽和啟用之外,也適合實作鍵盤快捷方式,例如 鍵盤快捷方式訪問鍵 ,以取得重要或常用功能。

快捷方式是一種鍵盤組合,可讓使用者有效率地存取應用程式功能。 快捷鍵有兩種:

  • 加速器是呼叫應用程式命令的捷徑。 您的應用程式可能或可能不會提供對應至命令的特定UI。 加速鍵通常由 Ctrl 鍵和字母鍵組成。
  • 存取金鑰是將焦點設定到應用程式中特定 UI 的快捷鍵。 存取金鑰通常是由 Alt 鍵加上字母金鑰所組成。

一律為依賴螢幕助讀程式和其他輔助技術的使用者提供簡單的方法,以探索您應用程式的快捷鍵。 您可以透過工具提示、可存取名稱、可存取描述或其他形式的螢幕通訊方式,來傳達快捷鍵。 請至少在應用程式的 [說明] 內容中清楚記錄快捷鍵。

您可以將 AutomationProperties.AccessKey 附加屬性設定為一個用來描述快捷鍵的字串,以透過螢幕助讀程式記錄存取按鍵。 還有一個 AutomationProperties.AcceleratorKey 附加屬性可用於記錄非助憶快捷鍵,儘管螢幕助讀程序通常會以相同的方式處理這兩個屬性。 請嘗試以多種方式記錄快捷鍵,包括工具提示、自動化屬性和書面說明文件。

下列範例示範如何記錄媒體播放、暫停和停止按鈕的快捷鍵。

<Grid KeyDown="Grid_KeyDown">

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <MediaElement x:Name="DemoMovie" Source="xbox.wmv"
    Width="500" Height="500" Margin="20" HorizontalAlignment="Center" />

  <StackPanel Grid.Row="1" Margin="10"
    Orientation="Horizontal" HorizontalAlignment="Center">

    <Button x:Name="PlayButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+P"
      AutomationProperties.AcceleratorKey="Control P">
      <TextBlock>Play</TextBlock>
    </Button>

    <Button x:Name="PauseButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+A"
      AutomationProperties.AcceleratorKey="Control A">
      <TextBlock>Pause</TextBlock>
    </Button>

    <Button x:Name="StopButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+S"
      AutomationProperties.AcceleratorKey="Control S">
      <TextBlock>Stop</TextBlock>
    </Button>
  </StackPanel>
</Grid>

重要

設定 AutomationProperties.AcceleratorKeyAutomationProperties.AccessKey 不會啟用鍵盤功能。 這隻會指出應該使用哪些密鑰來 使用者介面自動化 架構,然後可以透過輔助技術傳遞給使用者。

密鑰處理是在程式代碼後置中實作,而不是 XAML。 您仍然需要在相關控件上附加 KeyDown KeyUp 事件的處理程式,才能在應用程式中實際實作鍵盤快捷方式行為。 此外,不會自動為便捷鍵提供下底線的文字效果。 如果您希望在 UI 中顯示標有下底線的文字,則必須明確對助憶鍵中特定鍵的文字標註下底線,作為內嵌 Underline 格式。

為了簡單起見,上面的範例省略了字串資源的使用,例如「Ctrl+A」。 不過,在當地語系化期間也必須考慮快捷鍵。 快捷鍵的當地語系化之所以重要,是因為要選擇哪個鍵做為快捷鍵,通常取決於元素的可見文字標籤。

如需有關實作快捷鍵的進一步指引,請參閱 Windows User Experience Interaction Guidelines (Windows 使用者經驗指導方針) 中的快捷鍵

實作按鍵事件處理常式

輸入事件(例如重要事件)使用稱為 路由事件的事件概念。 路由事件可以透過父複合控件的子元素反升,讓父控件可以處理多個子元素的事件。 這個事件模型對於包含數個子元素的控件定義快捷鍵動作很方便,其中沒有任何專案可以擁有焦點或屬於定位順序的一部分。

您可以在撰寫按鍵事件處理常式時,加入用來檢查 Ctrl 鍵等輔助按鍵的功能;如需範例程式碼,請參閱鍵盤互動

使用鍵盤導覽自訂控制項

如果子專案彼此有疏散關係,建議使用箭頭鍵做為鍵盤快捷方式,以在子元素之間巡覽。 如果樹狀結構檢視使用個別的子元素來處理展開/收合和節點啟用,請使用向左鍵和向右鍵提供鍵盤展開/收合功能。 如果您有一個定向控制項支援在控制項内容中定向周遊,請使用對應的方向鍵。

一般而言,您會在類別邏輯中包含 OnKeyDown OnKeyUp 方法的覆寫,以實作自定義控件的自定義密鑰處理。

焦點指標的視覺狀態範例

如先前所述,任何支援焦點的自定義控件都應該有視覺焦點指標。 一般而言,該焦點指標只是一個矩形,以大綱顯示控件的周框。 用來當做視覺焦點的 Rectangle 是控制項範本中其餘控制項組成部分的對等元素,但一開始會將 Visibility 值設定為 Collapsed,因為控制項尚未獲得焦點。 當控件取得焦點時,會叫用視覺狀態,特別將焦點視覺效果的 Visibility 設定Visible。 一旦將焦點移動至別處,就會呼叫另一個視覺狀態,而 Visibility 會變成 Collapsed

所有可聚焦的 XAML 控件都會在焦點時顯示適當的視覺焦點指標。 用戶選取的使用者也可以影響指標外觀(特別是如果使用者使用高對比度模式)。 如果您在 UI 中使用 XAML 控制項(且未取代控制樣本),則不需要執行任何額外動作來取得預設視覺焦點指標。 不過,如果您想要重新範本化控件,或想知道 XAML 控件如何提供其視覺焦點指標,本節的其餘部分將說明如何在 XAML 和控件邏輯中完成此動作。

以下是一些來自 Button 之預設 XAML 範本的範例 XAML。

XAML

<ControlTemplate TargetType="Button">
...
    <Rectangle
      x:Name="FocusVisualWhite"
      IsHitTestVisible="False"
      Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
      StrokeEndLineCap="Square"
      StrokeDashArray="1,1"
      Opacity="0"
      StrokeDashOffset="1.5"/>
    <Rectangle
      x:Name="FocusVisualBlack"
      IsHitTestVisible="False"
      Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
      StrokeEndLineCap="Square"
      StrokeDashArray="1,1"
      Opacity="0"
      StrokeDashOffset="0.5"/>
...
</ControlTemplate>

目前仍僅處於組合階段。 若要控制焦點指標的可見性,您可以定義用來切換 Visibility 屬性的視覺狀態。 這需要使用 VisualStateManager 和 VisualStateManager.VisualStateGroups 附加屬性,並套用至用於定義組合的根元素。

<ControlTemplate TargetType="Button">
  <Grid>
    <VisualStateManager.VisualStateGroups>
       <!--other visual state groups here-->
       <VisualStateGroup x:Name="FocusStates">
         <VisualState x:Name="Focused">
           <Storyboard>
             <DoubleAnimation
               Storyboard.TargetName="FocusVisualWhite"
               Storyboard.TargetProperty="Opacity"
               To="1" Duration="0"/>
             <DoubleAnimation
               Storyboard.TargetName="FocusVisualBlack"
               Storyboard.TargetProperty="Opacity"
               To="1" Duration="0"/>
         </VisualState>
         <VisualState x:Name="Unfocused" />
         <VisualState x:Name="PointerFocused" />
       </VisualStateGroup>
     <VisualStateManager.VisualStateGroups>
<!--composition is here-->
   </Grid>
</ControlTemplate>

請注意,只有其中一個具名狀態會直接調整 Visibility ,而其他狀態顯然是空的。 使用視覺狀態時,只要控件使用相同 VisualStateGroup 的另一個狀態,就會立即取消先前狀態所套用的任何動畫。 由於組合的預設 VisibilityCollapsed,因此不會顯示矩形。 控制邏輯進行控制的方法包括接聽 GotFocus 等焦點事件,以及使用 GoToState 來變更狀態。 如果您使用預設控制項、或基於已具有該行為的控制項進行自訂,通常這已為您處理完成。

沒有硬體鍵盤的鍵盤輔助功能和裝置

某些裝置沒有專用的硬體鍵盤,而是依賴軟體輸入面板(SIP)。 螢幕助讀程式可以從文字 SIP 讀取文字輸入,使用者可以探索其手指的位置,因為螢幕助讀程式可以偵測到使用者正在掃描密鑰,並大聲讀取掃描的密鑰名稱。 此外,有些以鍵盤為導向的無障礙概念可以對應至完全不使用鍵盤的相關輔助技術行為。 例如,即使 SIP 不會包含 Tab 鍵,朗讀程式仍支援觸控手勢,相當於按下 Tab 鍵,因此在 UI 中透過控件擁有有用的定位順序仍然很適合輔助功能。 朗讀程式也支援許多其他觸控手勢,包括用於在複雜控件內流覽的箭頭鍵(請參閱 朗讀程序鍵盤命令和觸控手勢)。

範例

提示

WinUI 3 資源庫應用程式內含大多數 WinUI 3 控制項和功能的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼