キーボードのアクセシビリティ

(従来の、変更された、またはキーボード エミュレーション ハードウェア用の) キーボード アクセシビリティをアプリに組み込み、視覚障碍、視覚障碍、運動障碍のあるユーザー、または手をほとんどまたはまったく使っていないユーザーに、アプリの全機能をナビゲートして使用する機能を提供します。 さらに、障穏のないユーザーは、ユーザー設定や効率のためにナビゲーション用のキーボードを選択する場合があります。

アプリが適切なキーボード アクセスを提供しない場合、視覚障碍のあるユーザーやモビリティの問題があるユーザーは、アプリの使用が困難になる可能性があります。

UI 要素間のキーボード ナビゲーション

キーボードを使用してコントロールを操作するには、コントロールにフォーカスが必要です。 (ポインターを使用せずに) フォーカスを受け取る場合は、タブ ナビゲーションからコントロールにアクセスできる必要があります。 既定では、コントロールのタブ オーダーは、デザイン サーフェイスに追加される順序、XAML で宣言された順序、またはプログラムによってコンテナーに追加される順序と同じです。

通常、既定のタブ オーダーは、XAML でのコントロールの定義方法に基づいています。特に、スクリーン リーダーによってコントロールが走査される順序に基づいています。 ただし、既定の順序は必ずしも視覚的な順序に対応するとは限りません。 実際の表示位置は、親レイアウト コンテナーと、レイアウトに影響を与える可能性がある子要素のさまざまなプロパティによって異なります。

アプリのタブ オーダーが最適であることを確認するには、自分で動作をテストします。 レイアウトにグリッドまたはテーブルを使用する場合、ユーザーが画面を読み取る順序とタブ オーダーが大きく異なる場合があります。 これは常に問題であるとは限りませんが、タッチとキーボードの両方を使用してアプリの機能をテストして、UI が両方の入力方法に最適化されていることを確認してください。

XAML を調整するか、既定のタブ オーダーをオーバーライドすることで、タブ オーダーをビジュアルの順序と一致させることができます。 次の例では、列優先のタブ ナビゲーションを使用する Grid レイアウトで TabIndex プロパティを使用する方法を示します。

<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 など) が含まれますが、これらは静的なテキスト要素であるため、タブ オーダーには含まれません。 これらのコントロールは、従来は対話型ではありません (呼び出すことはできません。テキスト入力は必要ありませんが、テキスト内の選択ポイントの検索と調整をサポートする Text コントロール パターン をサポートします)。 テキスト コントロールは、支援技術によって引き続き検出され、スクリーン リーダーで読み上げられますが、タブ オーダー以外の手法に依存します。

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 の重要なコントロールに アクセス キー を追加します。

ショートカットとアクセス キーの実装に関する詳細なガイダンスについては Keyboard のショートカット 以下と Access キー を参照してください。

F6 の最適化

F6 キーを使用すると、キーボード ユーザーは、何百ものコントロールをタブ移動することなく、UI のウィンドウ間を効率的に移動できます。

たとえば、Microsoft Edge の F6 キーは、アドレス バー、ブックマーク バー、タブ バー、コンテンツ パネルの間を循環します。 Web ページには数百のタブ可能なコントロールが含まれる可能性があるため、F6 キーを押して、キーボード ユーザーがアプリケーション固有のショートカットを使用せずにタブ バーとアドレス バーに簡単にアクセスできます。

F6 タブ サイクルは、コンテンツ内の の見出しや見出し に疎に対応することもできますが、正確に一致する必要はありません。 F6 では、UI 内の大規模で個別のリージョンに焦点を当てる必要があります。一方、ランドマークはより細かい場合があります。 たとえば、アプリ バーとその検索ボックスをランドマークとしてマークし、F6 サイクルにはアプリ バー自体のみを含めることができます。

重要

F6 ナビゲーションはネイティブでサポートされていないため、アプリに実装する必要があります。

可能な場合、F6 サイクルのリージョンには、ランドマークを使用するか、リージョンの "ルート" 要素に AutomationProperties.Name を手動で追加して、アクセス可能な名前を付ける必要があります。

Shift キーを押しながら F6 キー を押すと、逆方向に循環します。

UI 要素内のキーボード ナビゲーション

複合コントロールの場合は、含まれている要素間で適切な内部ナビゲーションを確保することが重要です。 複合コントロールでは、現在アクティブな子要素を管理して、すべての子要素がフォーカスをサポートするオーバーヘッドを軽減できます。 複合コントロールはタブ オーダーに含まれており、キーボード ナビゲーション イベント自体を処理します。 多くの複合コントロールには、イベント処理に内部ナビゲーション ロジックが既に組み込まれています。 たとえば、 ListViewGridViewListBox および FlipView コントロールでは、項目の方向キートラバーサルが既定で有効になります。

特定のコントロール要素のポインター アクションとイベントに代わるキーボード

クリックできる UI 要素は、キーボードから呼び出すこともできます。 UI 要素でキーボードを使用するには、要素にフォーカスが必要です ( Control から派生したクラスのみ フォーカスとタブ ナビゲーションをサポートします)。

呼び出すことができる UI 要素の場合は、Space キーと Enter キーのキーボード イベント ハンドラーを実装します。 これにより、基本的なキーボード アクセシビリティのサポートが保証され、ユーザーはすべての対話型 UI 要素にアクセスし、キーボードのみを使用して機能をアクティブ化できます。

要素がフォーカスをサポートしていない場合は、独自のカスタム コントロールを作成できます。 この場合、フォーカスを有効にするには、 IsTabStop プロパティを true に設定する必要があります。また フォーカスインジケーターを使用して、フォーカスされた表示状態を視覚的に示す値を指定する必要があります。

ただし、タブストップ、フォーカス、および Microsoft UI オートメーション ピアとパターンのサポートが、コンテンツの作成を選択したコントロールによって処理されるように、コントロールコンポジションを使用する方が簡単な場合があります。 たとえば、 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>

キーボード ショートカット

キーボード ナビゲーションとアクティブ化を実装するだけでなく、重要な機能や頻繁に使用される機能のために、keyboard アクセラレータアクセス キーなどのキーボード ショートカットを実装することもお勧めします。

shortcutは、ユーザーがアプリ機能にアクセスするための効率的な方法を提供するキーボードの組み合わせです。 ショートカットには 2 つの種類があります。

  • アクセラレータは、アプリ コマンドを呼び出すショートカットです。 アプリには、そのコマンドに対応する特定の 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.AcceleratorKey または AutomationProperties.AccessKey を設定しても、キーボード機能は有効になりません。 これは、UI オートメーション フレームワークにどのキーを使用し、支援技術を使用してユーザーに渡すことができるかを示すだけです。

キー処理は、XAML ではなく分離コードで実装されます。 アプリでキーボード ショートカットの動作を実際に実装するには、関連するコントロールの KeyDown または KeyUp イベントのハンドラーをアタッチする必要があります。 また、アクセス キーの下線も自動的には追加されません。 UI で下線付きのテキストを表示する場合は、インラインの Underline 書式設定として、ニーモニックの特定のキーのテキストに明示的に下線を表示する必要があります。

わかりやすくするために、前の例では、"Ctrl + A" などの文字列に対するリソースの使用を省略しています。 ただし、ローカライズ時にはショートカット キーも考慮する必要があります。 ショートカット キーとして使用するキーの選択は、通常、要素の表示テキスト ラベルによって異なるため、ショートカット キーのローカライズが関連します。

ショートカット キーの実装に関する詳細なガイダンスについては、「Windows ユーザー エクスペリエンスの操作ガイドライン」の「 Shortcut キー を参照してください。

キー イベント ハンドラーの実装

入力イベント (キー イベントなど) では、 ルーティング イベントと呼ばれるイベントの概念が使用。 ルーティング イベントは、親コントロールが複数の子要素のイベントを処理できるように、親複合コントロールの子要素をバブル アップできます。 このイベント モデルは、複数の子要素を含むコントロールのショートカット キー アクションを定義する場合に便利です。いずれの子要素にもフォーカスを設定したり、タブ オーダーに含めたりすることはできません。

Ctrl キーなどの修飾子のチェックを含むキー イベント ハンドラーを記述する方法を示すコード例については、「 Keyboard 操作を参照してください。

カスタム コントロールのキーボード ナビゲーション

子要素が相互に社会的な関係を持つ場合は、子要素間を移動するためのキーボード ショートカットとして方向キーを使用することをお勧めします。 ツリー ビュー ノードに展開/折りたたみとノードのアクティブ化を処理するための個別のサブ要素がある場合は、左方向キーと右方向キーを使用してキーボードの展開/折りたたみ機能を提供します。 コントロール コンテンツ内で方向トラバーサルをサポートする指向コントロールがある場合は、適切な方向キーを使用します。

一般に、クラス ロジックの一部として OnKeyDown メソッドと OnKeyUp メソッドのオーバーライドを含めることで、カスタム コントロールのカスタム キー処理を実装します。

フォーカス インジケーターの表示状態の例

前述のように、フォーカスをサポートするカスタム コントロールには、視覚的なフォーカス インジケーターが必要です。 通常、そのフォーカス インジケーターは、コントロールの外接する四角形のアウトラインを示す単なる四角形です。 ビジュアル フォーカスの Rectangle は、コントロール テンプレート内のコントロールの他のコンポジションのピア要素ですが、コントロールがまだフォーカスされていないため、最初は Visibility Collapsed の値で設定されます。 コントロールがフォーカスを取得すると、フォーカス ビジュアルの VisibilityVisible に明示的に設定する表示状態が呼び出されます。 フォーカスが別の場所に移動されると、別の表示状態が呼び出され、 VisibilityCollapsed になります。

フォーカス可能なすべての 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>

名前付き状態の 1 つだけが Visibility を直接調整する一方で、他の状態は明らかに空であることに注意してください。 表示状態では、コントロールが同じ VisualStateGroup の別の状態を使用するとすぐに、前の状態によって適用されたすべてのアニメーションが直ちに取り消されます。 既定の Visibility from composition は Collapsed であるため、四角形は表示されません。 コントロール ロジックは、 GotFocus などのフォーカス イベントをリッスンし、 GoToState で状態を変更することで、これを制御します。 多くの場合、既定のコントロールを使用している場合や、その動作が既に設定されているコントロールに基づいてカスタマイズしている場合は、この処理が既に行われます。

ハードウェア キーボードのないキーボード アクセシビリティとデバイス

一部のデバイスには専用のハードウェア キーボードがなく、代わりにソフト入力パネル (SIP) に依存しています。 スクリーン リーダーは、 Text SIP からテキスト入力を読み取ることができ、ユーザーは、スクリーン リーダーがユーザーがキーをスキャンしていることを検出し、スキャンしたキー名を読み上げることができるため、指の位置を検出できます。 また、キーボード指向のアクセシビリティの概念の一部は、キーボードをまったく使用しない関連する支援技術の動作にマップできます。 たとえば、SIP に Tab キーが含まれていない場合でも、ナレーターは Tab キーを押すのと同等のタッチ ジェスチャをサポートしているため、UI のコントロールを介して便利なタブ オーダーを使用することは、アクセシビリティのために引き続き重要です。 ナレーターは、複雑なコントロール内を移動するための方向キーなど、他の多くのタッチ ジェスチャもサポートしています (「 ナレーター キーボード コマンドとタッチ ジェスチャ」を参照してください)。

ヒント

WinUI 3 ギャラリー アプリには、ほとんどの WinUI 3 コントロールと機能の対話型の例が含まれています。 Microsoft Store からアプリを入手するか、GitHub でソース コードを取得します。