Freigeben über


Tastaturzugänglichkeit

Die Barrierefreiheit der Tastatur sollte als primäres Interaktionsmodell behandelt werden, nicht als sekundärer Fallback. Eine robuste Tastaturerfahrung unterstützt Benutzer mit unterschiedlichen Behinderungen und Einschränkungen (einschließlich Sehbehinderungen, Lernen, Bewegung/ Mobilität und Sprach-/Kommunikationsbehinderungen). Außerdem verbessert sie die Produktivität für Benutzer, die tastaturspezifische Interaktion bevorzugen, um Geschwindigkeit und Präzision zu erzielen.

Wenn der Tastaturzugriff unvollständig oder inkonsistent ist, können Benutzer den Zugriff auf kerne App-Funktionen verlieren, auch wenn zeigerinteraktion vollständig implementiert wird.

Tastaturnavigation zwischen UI-Elementen

Um mit einem Steuerelement über die Tastatur zu interagieren, müssen Steuerelemente fokussierbar und mittels Fokustraversierung erreichbar sein. Um den Fokus (ohne Zeiger) zu erhalten, muss das Steuerelement über die Registerkartennavigation zugänglich sein. Standardmäßig entspricht die Tabulatorreihenfolge von Steuerelementen der Reihenfolge, in der sie einer Gestaltungsfläche hinzugefügt, in XAML deklariert oder programmgesteuert einem Container hinzugefügt werden.

In vielen UIs ist dieses Standardverhalten akzeptabel und richtet sich an den Lesefluss. Die visuelle Reihenfolge und die Tastaturreihenfolge können jedoch je nach Containerlayout und Positionierung der untergeordneten Elemente abweichen. Diese Divergenz sollte absichtlich und getestet werden.

Explizite Validierung des Registerkartenverhaltens. Raster, Tabellen und ähnliche Layouts sind häufige Ursachen für einen Konflikt zwischen wahrgenommener Lesereihenfolge und Fokusreihenfolge. Testen Sie sowohl Tastatur- als auch Fingereingabeinteraktionspfade, um sicherzustellen, dass die Durchquerung effizient und vorhersehbar bleibt.

Um das Traversal mit visuellem Fluss auszurichten, können Sie XAML neu strukturieren oder TabIndex explizit zuweisen. Im folgenden Beispiel wird ein Grid mit Tabulatorreihenfolge der Spalten zuerst verwendet.

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

In einigen Szenarien sollte ein Element vom Durchlaufen der Registerkarte ausgeschlossen werden. Der Standardansatz besteht darin, IsEnabled auf "false" festzulegen, wodurch auch die Interaktion deaktiviert wird. Deaktivierte Steuerelemente werden automatisch aus der Tab-Reihenfolge entfernt.

Wenn ein Element über andere Mechanismen interaktiv bleibt, aber nicht mit Tab erreicht werden soll, legen Sie IsTabStop auf "false" fest.

Die meisten fokusfähigen Steuerelemente sind standardmäßig in der Tab-Reihenfolge enthalten. Eine häufige Ausnahme sind Textanzeigesteuerelemente wie RichTextBlock, die den Fokus für Textauswahl- und Zwischenablagevorgänge unterstützen können, in der Regel jedoch keine Tabstopps sind, da sie keine befehlsinternen Steuerelemente sind. Diese Steuerelemente können weiterhin von Hilfstechnologien durch Automatisierungsemantik wie das Text-Steuerelementmuster ermittelt werden.

Unabhängig davon, ob Sie standardmäßiges Traversal oder explizites TabIndex verwenden, gelten die folgenden Regeln:

  • Wenn TabIndex für ein Element nicht festgelegt ist, lautet der Standardwert Int32.MaxValue, und die Reihenfolge basiert auf der Deklarations-/Einfügereihenfolge.
  • Wenn TabIndex für ein Element festgelegt ist:
    • Elemente mit TabIndex gleich 0 werden basierend auf der Deklarations-/Einfügereihenfolge hinzugefügt.
    • Elemente mit TabIndex größer als 0 werden in aufsteigender TabIndex-Reihenfolge hinzugefügt.
    • Elemente mit TabIndex unter 0 werden vor Elementen mit Nullwerten hinzugefügt.

Der folgende Codeausschnitt zeigt gemischte TabIndex-Einstellungen (B verwendet Int32.MaxValue oder 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>

Dadurch wird die folgende Tabulatorreihenfolge erzeugt:

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

Tastaturnavigation zwischen Anwendungsbereichen mit F6

Ein Anwendungsbereich ist ein prominenter Aufgabenbereich innerhalb eines Fensters. In Microsoft Edge umfassen Bereiche beispielsweise die Adressleiste, die Textmarkenleiste, die Registerkartenleiste und den Inhaltsbereich. F6 wird häufig verwendet, um den Fokus zwischen diesen Bereichen mit untergeordneten Elementen zu verschieben, auf die mithilfe der standardmäßigen Tastaturnavigation zugegriffen werden kann.

Während ein kompatibles Tastaturnavigationsmodell die Basislinie ist, enthält ein verwendbares Tastaturnavigationsmodell in der Regel auch Folgendes:

  • Auf F6 lauschen, um zwischen wichtigen UI-Regionen zu wechseln.
  • Bereitstellen von Tastenkombinationen für Hochfrequenzbefehle.
  • Bereitstellen von Zugriffstasten für wichtige Steuerelemente.

Hinweise zur Implementierung finden Sie unter Tastenkombinationen und Zugriffstasten.

Optimieren für F6

F6 reduziert die Durchlaufkosten erheblich, indem Benutzer zwischen wichtigen Regionen springen können, anstatt durch jedes untergeordnete Steuerelement zu wechseln.

Beispielsweise wechselt F6 in Microsoft Edge zwischen der Adressleiste, der Textmarkenleiste, dem Tabstoppstreifen und dem Inhalt. Da eine Seite viele Tabstopps enthalten kann, macht dies gängige Navigationsaufgaben wesentlich effizienter.

Die F6-Sequenz kann an Orientierungspunkten oder Überschriften ausgerichtet werden, muss aber nicht exakt übereinstimmen. Verwenden Sie F6 für breite Bewegung auf Regionsebene und Orientierungspunkte/Überschriften für die semantische Struktur innerhalb und über Regionen hinweg.

Wichtig

Sie müssen F6-Navigation explizit in Ihrer App implementieren; sie wird nicht automatisch bereitgestellt.

Wenn möglich, sollte jeder F6-Zielbereich über einen eindeutigen barrierefreien Namen verfügen, entweder über die Landmark-Semantik oder durch Festlegen des AutomationProperties.Name im Regionsstamm.

UMSCHALT+F6 sollte denselben Zyklus in umgekehrter Reihenfolge durchlaufen.

Tastaturnavigation innerhalb eines UI-Elements

Zusammengesetzte Steuerelemente sollten eine vorhersagbare innere Navigation zwischen untergeordneten Elementen ermöglichen. Ein gängiges Muster besteht darin, den zusammengesetzten Stamm in der Aktivierreihenfolge beizubehalten und aktive Nachfolger intern zu verwalten, anstatt jedes untergeordnete Element als separaten Tabstopp verfügbar zu machen.

Viele integrierte Steuerelemente implementieren dieses Verhalten bereits. Beispielsweise ist die Pfeiltasten-Traversal standardmäßig für ListView, GridView, ListBox und FlipView verfügbar.

Tastaturalternativen zu Zeigeraktionen und Ereignissen für bestimmte Steuerelemente

Jede Benutzeroberfläche, die per Zeiger aktiviert werden kann, sollte auch über die Tastatur aufgerufen werden. Die Aktivierung erfordert, dass das Element den Fokus hat (nur Klassen, die vom Steuerelement abgeleitet werden, unterstützen den Fokus und die Registerkartennavigation).

Implementieren Sie für Steuerelemente, die aufgerufen werden können, Tastaturereignishandler für die Leertaste und die Eingabetaste. Dies bietet grundlegende Tastaturparität mit Zeigerinteraktionen.

Wenn ein Element standardmäßig nicht fokussierbar ist, verwenden Sie entweder einen fokussierbaren Steuerelementtyp, oder implementieren Sie ein benutzerdefiniertes Steuerelement mit explizitem Fokusverhalten. Legen Sie in diesem Fall IsTabStop auf "true " fest, und stellen Sie eine sichtbare Fokusanzeige bereit.

In vielen Fällen ist die Komposition einfacher und robuster als benutzerdefiniertes nur-Zeiger-Verhalten. Platzieren Sie es zum Beispiel anstelle der direkten Zeigereingaben auf einem Bild innerhalb einer Schaltfläche, um Tastaturaktivierung, Fokussteuerung und Automatisierungsverhalten zu übernehmen.

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

<!--Do this instead.-->
<Button Click="Button_Click"
        AutomationProperties.Name="Open profile photo">
  <Image Source="Assets/profile-photo.png"/>
</Button>

Tastenkombinationen

Implementieren Sie zusätzlich zur Navigation und Aktivierung eine Tastenkombination (eine Kombination aus Tasten, die einen effizienten Zugriff auf App-Funktionen bietet) für wichtige oder häufig verwendete Befehle mit Tastenkombinationen und Zugriffstasten.

Zwei gängige Tastenkombinationstypen sind:

  • Beschleuniger: Befehle werden direkt aufgerufen, mit oder ohne eine entsprechende sichtbare Steuerung.
  • Zugriffstasten: Setzen Sie den Fokus auf bestimmte Steuerelemente in der Benutzeroberfläche.

Machen Sie Verknüpfungen für Benutzer von Barrierefreiheitstechnologien immer leicht auffindbar. Kommunizieren Sie sie über QuickInfos, Automatisierungsmetadaten, sichtbare UI-Funktionen und Hilfedokumentation.

Um Verknüpfungsmetadaten für Hilfstechnologien verfügbar zu machen, verwenden Sie AutomationProperties.AccessKey für mnemonische Verknüpfungen und AutomationProperties.AcceleratorKey für Befehlsverknüpfungen. Da Bildschirmlesegeräte ähnliche Informationen möglicherweise auf gleiche Weise darstellen, dokumentieren Sie Verknüpfungen in mehreren Kanälen.

Im folgenden Beispiel wird veranschaulicht, wie Tastenkombinationen für die Medienwiedergabe, -pause und -stopptasten dokumentiert werden.

<Grid>

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

  <MediaPlayerElement x:Name="DemoPlayer"
    Width="500" Height="300" Margin="20"
    HorizontalAlignment="Center"
    AutoPlay="False"
    AreTransportControlsEnabled="True" />

  <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="Ctrl+P"
      AutomationProperties.AccessKey="Alt+P">
      <Button.KeyboardAccelerators>
        <KeyboardAccelerator Modifiers="Control" Key="P"/>
      </Button.KeyboardAccelerators>
      <TextBlock>Play</TextBlock>
    </Button>

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

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

Wichtig

Das Festlegen von AutomationProperties.AcceleratorKey oder AutomationProperties.AccessKey implementiert kein Tastaturverhalten. Diese Eigenschaften machen Metadaten für die Benutzeroberflächenautomatisierung verfügbar, sodass Hilfstechnologien die erwarteten Tastenkombinationen ankündigen können.

Das Tastaturverhalten muss weiterhin im Code implementiert werden. Verwenden Sie nach Möglichkeit deklarative KeyboardAccelerator-Definitionen , und verwenden Sie KeyDown - oder KeyUp-Handler , bei denen Sie benutzerdefinierte Routinglogik benötigen. Beachten Sie außerdem, dass die Unterstreichung von Zugriffstasten nicht automatisch erfolgt. Wenn Sie sichtbare Mnemonic-Unterstriche wünschen, sollten Sie sie explizit darstellen (z. B. mit Unterstrich).

Aus Platzgründen lässt das Beispiel Zeichenfolgenressourcen wie "STRG+A" weg. Lokalisieren Sie während der Produktion Tastenkürzel und validieren Sie Mnemonik-Auswahlmöglichkeiten pro Gebietsschema, da die Tastenauswahl häufig von übersetzten Bezeichnungen abhängt.

Weitere Anleitungen finden Sie in den Richtlinien für die Interaktion mit der Windows-Benutzeroberfläche unter Tastenkombinationen.

Implementieren eines Schlüsselereignishandlers

Die Tastatureingabe verwendet geroutete Ereignisse. Routingereignisse können von untergeordneten Elementen in einem blasenartigen Muster bis zu einem übergeordneten Container aufsteigen, wodurch das übergeordnete Element Tastenkombinationen für mehrere Nachfahrenelemente im Rahmen des Ereignisverarbeitungsmechanismus verarbeiten kann. Dieses Ereignismodell eignet sich für die Definition von Tastenkombinationen für ein Steuerelement, das mehrere untergeordnete Elemente enthält, von denen keines fokussiert werden kann oder in der Tabulatorreihenfolge steht.

Codebeispiele, die Modifizierertastenprüfungen (z. B. STRG) enthalten, finden Sie unter Tastaturinteraktionen.

Tastaturnavigation für benutzerdefinierte Steuerelemente

Verwenden Sie bei benutzerdefinierten Steuerelementen Pfeiltasten, wenn untergeordnete Elemente raumbezogen sind. In Strukturszenarien, in denen "Erweitern/Reduzieren" und "Aktivierung" separate Interaktionen sind, ordnen Sie die Linkspfeile und Rechtspfeile dazu, um das Verhalten des Erweitern/Reduzieren zu steuern. Ordnen Sie für orientierte Steuerelemente richtungsbezogene Tasten der visuellen Ausrichtung des Steuerelements zu.

Benutzerdefiniertes Schlüsselverhalten wird häufig durch Außerkraftsetzung von OnKeyDown und OnKeyUp implementiert.

Beispiel für einen visuellen Zustand für eine Fokusanzeige

Jedes fokussierbare benutzerdefinierte Steuerelement sollte eine klare visuelle Fokusanzeige anzeigen. Ein gängiges Vorlagenmuster verwendet eine Rechtecküberlagerung , die über Sichtbarkeit ausgeblendet wird und angezeigt wird, wenn der Fokus eintritt.

Integrierte XAML-Steuerelemente stellen bereits Fokusindikatoren bereit. Die genaue Erscheinung kann je nach Theme-Einstellungen variieren, einschließlich des Modus mit hohem Kontrast. Wenn Sie Steuerelemente neu erstellen, behalten Sie das entsprechende Verhalten der Fokussichtbarkeit bei.

Das folgende Beispiel wird aus der Standardvorlage "Schaltfläche" angepasst.

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

Verwenden Sie VisualStateManager und VisualStateManager.VisualStateGroups im Vorlagenstamm, um die Sichtbarkeit der Fokusanzeige umzuschalten.

<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"/>
          </Storyboard>
        </VisualState>
        <VisualState x:Name="Unfocused" />
        <VisualState x:Name="PointerFocused" />
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <!--composition is here-->
  </Grid>
</ControlTemplate>

Nur ein Zustand in dieser Gruppe modifiziert die Fokusanzeige explizit. Die anderen Zustände können leer bleiben, da Übergänge innerhalb derselben VisualStateGroup vorherige Zustandsanimationen abbrechen. Fokusereignisse wie GotFocus, kombiniert mit GoToState, steuern diese Übergänge in der Regel.

Tastaturzugänglichkeit und Geräte ohne Hardwaretastatur

Einige Geräte basieren auf einem Soft Input Panel (SIP) anstelle einer Hardwaretastatur. Bildschirmsprachausgaben können erkennen, dass der Benutzer Tasten scannt und die SIP-Tastensuche eines Benutzers vorliest, und viele Konzepte für die Barrierefreiheit der Tastatur gelten weiterhin durch Gestenäquivalente.

Der Narrator unterstützt z. B. auch ohne physische Tab-Taste Gesten zur Tab-Navigation. Das bedeutet, dass eine kohärente Tab-Reihenfolge immer noch wichtig ist. Die Sprachausgabe bietet Gestenäquivalente für die Richtungsnavigation in komplexen Steuerelementen (siehe Tastaturbefehle und Touchgesten der Sprachausgabe).

Beispiele

WinUI 3-Katalogsymbol Die WinUI 3 Gallery-App enthält interaktive Beispiele für WinUI-Steuerelemente und -Features. Rufen Sie die App aus dem Microsoft Store ab, oder durchsuchen Sie den Quellcode auf GitHub.