Delen via


Toetsenbordtoegankelijkheid

Het bouwen van toetsenbordtoegankelijkheid (voor traditionele, gewijzigde of toetsenbordemulatiehardware) in uw app biedt gebruikers die blind zijn, slechtziend zijn, motorische handicaps hebben of weinig of geen gebruik van hun handen hebben, de mogelijkheid om door de volledige functionaliteit van uw app te navigeren en te gebruiken. Daarnaast kunnen gebruikers zonder beperkingen het toetsenbord kiezen voor navigatie vanwege voorkeur of efficiëntie.

Als uw app geen goede toetsenbordtoegang biedt, kunnen gebruikers die blind zijn of mobiliteitsproblemen hebben problemen met het gebruik van uw app.

Toetsenbordnavigatie tussen UI-elementen

Als u wilt communiceren met een besturingselement met behulp van het toetsenbord, moet het besturingselement de focus hebben. Als u de focus wilt ontvangen (zonder een aanwijzer te gebruiken), moet het besturingselement toegankelijk zijn via tabnavigatie. Standaard is de tabvolgorde van besturingselementen hetzelfde als de volgorde waarin ze worden toegevoegd aan een ontwerpoppervlak, gedeclareerd in XAML of programmatisch worden toegevoegd aan een container.

Normaal gesproken is de standaardtabvolgorde gebaseerd op de wijze waarop besturingselementen worden gedefinieerd in XAML, met name omdat dat de volgorde is waarin de besturingselementen worden doorkruist door schermlezers. De standaardvolgorde komt echter niet noodzakelijkerwijs overeen met de visuele volgorde. De werkelijke weergavepositie kan afhankelijk zijn van de bovenliggende indelingscontainer en verschillende eigenschappen van onderliggende elementen die van invloed kunnen zijn op de indeling.

Test het gedrag zelf om ervoor te zorgen dat uw app een optimale tabvolgorde heeft. Als u een raster of tabel gebruikt voor uw indeling, kan de volgorde waarin gebruikers het scherm lezen versus de tabvolgorde heel anders zijn. Dit is niet altijd een probleem, maar zorg ervoor dat u de functionaliteit van uw app test via zowel aanraakscherm als toetsenbord om te controleren of uw gebruikersinterface is geoptimaliseerd voor beide invoermethoden.

U kunt de tabvolgorde aanpassen aan de visuele volgorde door de XAML aan te passen of de standaardtabvolgorde te overschrijven. In het volgende voorbeeld ziet u hoe u de eigenschap TabIndex gebruikt met een rasterindeling die gebruikmaakt van navigatie op het eerste tabblad.

<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 sommige gevallen wilt u mogelijk een specifiek besturingselement uitsluiten van de tabvolgorde. Dit wordt meestal bereikt door het besturingselement niet-interactief te maken door de eigenschap IsEnabled in te stellen op false. Een uitgeschakeld besturingselement wordt automatisch uitgesloten van de tabvolgorde.

Als u een interactief besturingselement wilt uitsluiten van de tabvolgorde, kunt u de eigenschap IsTabStop instellen op false.

Ui-elementen die de focus ondersteunen, worden standaard opgenomen in de tabvolgorde. Enkele uitzonderingen hierop zijn bepaalde typen tekstweergave (zoals RichTextBlock) die de focus voor tekstselectie en klembordtoegang ondersteunen, maar die niet in de tabvolgorde staan omdat het statische tekstelementen zijn. Deze besturingselementen zijn niet conventioneel interactief (ze kunnen niet worden aangeroepen en vereisen geen tekstinvoer, maar ondersteunen wel het tekstbesturingselementpatroon dat ondersteuning biedt voor het zoeken en aanpassen van selectiepunten in tekst). Tekstbesturingselementen worden nog steeds gedetecteerd door ondersteunende technologieën en hardop voorgelezen in schermlezers, maar die afhankelijk zijn van andere technieken dan tabvolgorde.

Of u nu TabIndex-waarden aanpast of de standaardvolgorde gebruikt, de volgende regels zijn van toepassing:

  • Als TabIndex niet is ingesteld op een element, is de standaardwaarde Int32.MaxValue en is de tabvolgorde gebaseerd op de declaratievolgorde in de XAML- of onderliggende verzamelingen.
  • Als TabIndex is ingesteld op een element:
    • UI-elementen met TabIndex gelijk aan 0 worden toegevoegd aan de tabvolgorde op basis van de declaratievolgorde in XAML- of onderliggende verzamelingen.
    • UI-elementen met TabIndex groter dan 0 worden toegevoegd aan de tabvolgorde op basis van de TabIndex-waarde .
    • UI-elementen met TabIndex kleiner dan 0 worden toegevoegd aan de tabvolgorde en worden weergegeven vóór een nulwaarde.

In het volgende codefragment ziet u een verzameling elementen met verschillende TabIndex-instellingen (B wordt de waarde van Int32.MaxValue of 2.147.483.647 toegewezen).

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

Dit resulteert in de volgende tabvolgorde:

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

Toetsenbordnavigatie tussen toepassingsvensters met F6

Een toepassingsvenster is een logisch gebied van prominente, gerelateerde gebruikersinterface in een toepassingsvenster (microsoft Edge-deelvensters bevatten bijvoorbeeld de adresbalk, de bladwijzerbalk, de tabbalk en het inhoudsvenster). De F6-toets kan worden gebruikt om tussen deze deelvensters te navigeren, waar groepen onderliggende elementen vervolgens kunnen worden geopend met behulp van standaardtoetsenbordnavigatie.

Hoewel toetsenbordnavigatie een toegankelijke gebruikersinterface kan bieden, zijn er vaak nog enkele stappen nodig om een toegankelijke gebruikersinterface te maken. Dit omvat doorgaans:

  • Luisteren naar F6 om te navigeren tussen belangrijke secties van uw gebruikersinterface.
  • Sneltoetsen toevoegen voor algemene acties in uw gebruikersinterface.
  • Toegangssleutels toevoegen aan belangrijke besturingselementen in uw gebruikersinterface.

Zie de onderstaande sneltoetsen en toegangstoetsen voor meer informatie over het implementeren van sneltoetsen en toegangstoetsen.

Optimaliseren voor F6

Met F6 kunnen toetsenbordgebruikers efficiënt navigeren tussen deelvensters van de gebruikersinterface zonder dat ze door mogelijk honderden besturingselementen hoeven te bladeren.

F6 in Microsoft Edge cycli bijvoorbeeld tussen de adresbalk, de bladwijzerbalk, de tabbalk en het inhoudsvenster. Omdat een webpagina mogelijk honderden besturingselementen met tabbladen kan bevatten, kan F6 het voor toetsenbordgebruikers gemakkelijker maken om de tabbalk en adresbalk te bereiken zonder toepassingsspecifieke sneltoetsen te gebruiken.

De tabcyclus F6 kan ook losjes overeenkomen met oriëntatiepunten of koppen in inhoud, maar hoeft niet exact overeen te komen. F6 moet zich richten op grote, afzonderlijke regio's in uw gebruikersinterface, terwijl oriëntatiepunten nauwkeuriger kunnen zijn. U kunt bijvoorbeeld een app-balk en het zoekvak markeren als oriëntatiepunten, maar alleen de app-balk zelf opnemen in de F6-cyclus.

Belangrijk

U moet F6-navigatie in uw app implementeren omdat deze niet systeemeigen wordt ondersteund.

Waar mogelijk moeten regio's in de F6-cyclus een toegankelijke naam hebben: via een oriëntatiepunt of door handmatig een AutomationProperties.Name toe te voegen aan het hoofdelement van de regio.

Shift-F6 moet in tegengestelde richting fietsen.

Toetsenbordnavigatie in een UI-element

Voor samengestelde besturingselementen is het belangrijk om de juiste binnennavigatie tussen de ingesloten elementen te garanderen. Een samengesteld besturingselement kan het momenteel actieve onderliggende element beheren om de overhead van alle onderliggende elementen te beperken. Het samengestelde besturingselement is opgenomen in de tabvolgorde en verwerkt de toetsenbordnavigatiegebeurtenissen zelf. Veel samengestelde besturingselementen hebben al enige interne navigatielogica ingebouwd in hun gebeurtenisafhandeling. Het doorkruisen van items met pijltoetsen is bijvoorbeeld standaard ingeschakeld voor de besturingselementen ListView, GridView, ListBox en FlipView .

Toetsenbordalternatieven voor aanwijzeracties en -gebeurtenissen voor specifieke besturingselementen

Ui-elementen waarop kan worden geklikt, moeten ook via het toetsenbord kunnen worden aangetrokken. Als u het toetsenbord wilt gebruiken met een UI-element, moet het element de focus hebben (alleen klassen die zijn afgeleid van de focus en tabnavigatie van Control ).

Implementeer voor UI-elementen die kunnen worden aangeroepen de handlers voor toetsenbordgebeurtenissen voor de spatiebalk en Enter-toetsen. Dit zorgt voor eenvoudige ondersteuning voor toetsenbordtoegankelijkheid en stelt gebruikers in staat alle interactieve UI-elementen te bereiken en functionaliteit alleen te activeren met behulp van het toetsenbord.

Wanneer een element geen focus ondersteunt, kunt u uw eigen aangepaste besturingselement maken. Als u de focus wilt inschakelen, moet u de eigenschap IsTabStop instellen op true en moet u een visuele indicatie opgeven van de status van de visual met prioriteit met een focusindicator.

Het kan echter eenvoudiger zijn om de samenstelling van besturingselementen te gebruiken, zodat de ondersteuning voor tabstops, focus en Microsoft UI Automation-peers en -patronen wordt verwerkt door het besturingselement waarin u ervoor kiest om uw inhoud op te stellen. In plaats van bijvoorbeeld een aanwijzergedrukte gebeurtenis op een afbeelding te verwerken, verpakt u dat element in een knop om ondersteuning voor aanwijzer, toetsenbord en focus te krijgen.

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

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

Sneltoetsen op het toetsenbord

Naast het implementeren van toetsenbordnavigatie en activering is het ook een goede gewoonte om sneltoetsen zoals toetsenbordversnellers en toegangstoetsen te implementeren voor belangrijke of veelgebruikte functionaliteit.

Een sneltoets is een toetsenbordcombinatie die een efficiënte manier biedt voor de gebruiker om toegang te krijgen tot app-functionaliteit. Er zijn twee soorten sneltoetsen:

  • Accelerators zijn sneltoetsen waarmee een app-opdracht wordt aangeroepen. Uw app biedt mogelijk of niet specifieke gebruikersinterface die overeenkomt met de opdracht. Accelerators bestaan doorgaans uit de Ctrl-toets plus een lettertoets.
  • Toegangstoetsen zijn sneltoetsen waarmee de focus wordt ingesteld op een specifieke gebruikersinterface in uw toepassing. Toegangstoetsen bestaan doorgaans uit de Alt-toets plus een lettertoets.

Altijd een eenvoudige manier bieden voor gebruikers die afhankelijk zijn van schermlezers en andere ondersteunende technologie om de sneltoetsen van uw app te ontdekken. Sneltoetsen communiceren met behulp van knopinfo, toegankelijke namen, toegankelijke beschrijvingen of een andere vorm van communicatie op het scherm. Sneltoetsen moeten minimaal goed worden gedocumenteerd in de Help-inhoud van uw app.

U kunt toegangssleutels documenteren via schermlezers door de eigenschap AutomationProperties.AccessKey in te stellen op een tekenreeks die de sneltoets beschrijft. Er is ook een eigenschap AutomationProperties.AcceleratorKey gekoppeld voor het documenteren van niet-nemonische sneltoetsen, hoewel schermlezers in het algemeen beide eigenschappen op dezelfde manier behandelen. Probeer sneltoetsen op meerdere manieren te documenteren, met behulp van knopinfo, automatiseringseigenschappen en schriftelijke Help-documentatie.

In het volgende voorbeeld ziet u hoe u sneltoetsen voor media afspelen, onderbreken en stoppen kunt documenteren.

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

Belangrijk

Als u AutomationProperties.AcceleratorKey of AutomationProperties.AccessKey instelt, wordt de toetsenbordfunctionaliteit niet ingeschakeld. Dit geeft alleen aan welke sleutels moeten worden gebruikt voor het UI Automation-framework en vervolgens kan worden doorgegeven aan gebruikers via ondersteunende technologieën.

Sleutelafhandeling wordt geïmplementeerd in code-behind, niet in XAML. U moet nog steeds handlers koppelen voor KeyDown - of KeyUp-gebeurtenissen op het relevante besturingselement om het gedrag van de sneltoets in uw app daadwerkelijk te implementeren. Ook wordt de onderstrepingstekstversiering voor een toegangssleutel niet automatisch verstrekt. U moet de tekst voor de specifieke sleutel in uw nemonic expliciet onderstrepen als inline onderstrepen als u onderstreepte tekst in de gebruikersinterface wilt weergeven.

Ter vereenvoudiging laat het voorgaande voorbeeld het gebruik van resources voor tekenreeksen zoals Ctrl+A weg. U moet echter ook sneltoetsen overwegen tijdens lokalisatie. Het lokaliseren van sneltoetsen is relevant omdat de keuze van de sleutel die moet worden gebruikt als sneltoets, doorgaans afhankelijk is van het zichtbare tekstlabel voor het element.

Zie sneltoetsen in de richtlijnen voor interactie met Windows-gebruikerservaring voor meer informatie over het implementeren van sneltoetsen .

Een sleutel-gebeurtenis-handler implementeren

Invoergebeurtenissen (zoals de sleutelgebeurtenissen) gebruiken een gebeurtenisconcept dat gerouteerde gebeurtenissen wordt genoemd. Een gerouteerde gebeurtenis kan omhoog bellen via de onderliggende elementen van een bovenliggend samengesteld besturingselement, zodat het bovenliggende besturingselement gebeurtenissen voor meerdere onderliggende elementen kan verwerken. Dit gebeurtenismodel is handig voor het definiëren van sneltoetsacties voor een besturingselement dat verschillende onderliggende elementen bevat, waarvan geen enkele focus kan hebben of deel kan uitmaken van de tabvolgorde.

Code die laat zien hoe u een gebeurtenis-handler voor sleutels schrijft, waaronder het controleren op modifiers zoals de Ctrl-toets, raadpleegt u Toetsenbordinteracties.

Toetsenbordnavigatie voor aangepaste besturingselementen

U wordt aangeraden de pijltoetsen te gebruiken als sneltoetsen voor het navigeren tussen onderliggende elementen in gevallen waarin de onderliggende elementen een spaciale relatie met elkaar hebben. Als knooppunten in de structuurweergave afzonderlijke subelementen hebben voor het afhandelen van samenvouwen en activering van knooppunten, gebruikt u de pijl-links en pijl-rechts om functionaliteit voor het uitvouwen en samenvouwen van het toetsenbord te bieden. Als u een georiënteerd besturingselement hebt dat richtingskruising binnen de inhoud van het besturingselement ondersteunt, gebruikt u de juiste pijltoetsen.

Over het algemeen implementeert u aangepaste sleutelafhandeling voor aangepaste besturingselementen door een onderdrukking van de Methoden OnKeyDown en OnKeyUp op te tellen als onderdeel van de klasselogica.

Een voorbeeld van een visuele status voor een focusindicator

Zoals eerder vermeld, moet elk aangepast besturingselement dat de focus ondersteunt, een visuele focusindicator hebben. Normaal gesproken is die focusindicator slechts een rechthoek die de begrenzingsrechthoek van het besturingselement weergeeft. De rechthoek voor visuele focus is een peerelement voor de rest van de samenstelling van het besturingselement in een besturingssjabloon, maar is in eerste instantie ingesteld met de waarde Zichtbaarheidsamengevouwen omdat het besturingselement nog niet is gericht. Wanneer het besturingselement de focus krijgt, wordt een visuele status aangeroepen waarmee de zichtbaarheid van de focusvisual specifiek wordt ingesteld op Zichtbaar. Zodra de focus ergens anders is verplaatst, wordt een andere visuele status aangeroepen en wordt de zichtbaarheidsamengevouwen.

Alle focusbare XAML-besturingselementen geven een geschikte visuele focusindicator weer wanneer deze is gericht. De geselecteerde gebruiker kan ook van invloed zijn op het uiterlijk van de indicator (met name als de gebruiker een modus met hoog contrast gebruikt). Als u de XAML-besturingselementen in uw gebruikersinterface gebruikt (en de besturingssjablonen niet vervangt), hoeft u niets extra te doen om standaard visuele focusindicatoren op te halen. Als u echter van plan bent een besturingselement opnieuw tetemplateen of als u wilt weten hoe XAML-besturingselementen hun visuele focusindicatoren bieden, wordt in de rest van deze sectie uitgelegd hoe dit in XAML en de besturingslogica wordt gedaan.

Hier volgt een voorbeeld van XAML die afkomstig is van de standaard XAML-sjabloon voor een knop.

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>

Tot nu toe is dit alleen de compositie. Als u de zichtbaarheid van de focusindicator wilt beheren, definieert u de visuele statussen die de eigenschap Zichtbaarheid in-/uitschakelen. Dit wordt gedaan met behulp van visualStateManager en de gekoppelde eigenschap VisualStateManager.VisualStateGroups, zoals toegepast op het hoofdelement dat de samenstelling definieert.

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

U ziet dat slechts één van de benoemde statussen de zichtbaarheid rechtstreeks aanpast, terwijl de andere duidelijk leeg zijn. Wanneer het besturingselement een andere status van dezelfde VisualStateGroup gebruikt, worden animaties die door de vorige status zijn toegepast, onmiddellijk geannuleerd. Omdat de standaardweergave van de samenstelling is samengevouwen, wordt de rechthoek niet weergegeven. De besturingslogica bepaalt dit door te luisteren naar focusevenementen zoals GotFocus en de statussen te wijzigen met GoToState. Dit wordt vaak al voor u afgehandeld als u een standaard besturingselement gebruikt of aanpassen op basis van een besturingselement dat dat gedrag al heeft.

Toetsenbordtoegankelijkheid en apparaten zonder hardwaretoetsenbord

Sommige apparaten hebben geen toegewezen hardwaretoetsenbord en zijn in plaats daarvan afhankelijk van een SIP (Soft Input Panel). Schermlezers kunnen tekstinvoer lezen van de Text SIP en gebruikers kunnen ontdekken waar hun vingers zich bevinden, omdat de schermlezer kan detecteren dat de gebruiker sleutels scant en de gescande sleutelnaam hardop leest. Daarnaast kunnen sommige van de toetsenbordgerichte toegankelijkheidsconcepten worden toegewezen aan gerelateerd gedrag van ondersteunende technologie die helemaal geen toetsenbord gebruiken. Hoewel een SIP bijvoorbeeld geen Tab-toets bevat, ondersteunt Verteller een aanraakbeweging die het equivalent is van het drukken op de Tab-toets, zodat het gebruik van een handige tabvolgorde via de besturingselementen in een gebruikersinterface nog steeds onpraktisch is voor toegankelijkheid. Verteller ondersteunt ook veel andere aanraakbewegingen, waaronder pijltoetsen voor het navigeren in complexe besturingselementen (zie Toetsenbordopdrachten en aanraakbewegingen van Verteller).

Voorbeelden

De WinUI 3 Gallery-app bevat interactieve voorbeelden van de meeste Besturingselementen, functies en functionaliteit van WinUI 3. Haal de app op uit de Microsoft Store of haal de broncode op GitHub op