Condividi tramite


Accessibilità tramite tastiera

La compilazione dell'accessibilità tramite tastiera (per hardware tradizionale, modificato o di emulazione della tastiera) nell'app offre agli utenti che sono ciechi, hanno ipovedenti, disabilità motorie o hanno poco o nessun uso delle mani, la possibilità di spostarsi e usare la funzionalità completa dell'app. Inoltre, gli utenti senza disabilità potrebbero scegliere la tastiera per lo spostamento a causa della preferenza o dell'efficienza.

Se l'app non fornisce un buon accesso tramite tastiera, gli utenti non vedenti o hanno problemi di mobilità potrebbero avere difficoltà a usare l'app.

Spostamento tramite tastiera tra gli elementi dell'interfaccia utente

Per interagire con un controllo tramite la tastiera, il controllo deve avere lo stato attivo. Per ricevere lo stato attivo (senza usare un puntatore), il controllo deve essere accessibile tramite lo spostamento tramite tabulazione. Per impostazione predefinita, l'ordine di tabulazione dei controlli corrisponde all'ordine in cui vengono aggiunti a un'area di progettazione, dichiarati in XAML o aggiunti a livello di codice a un contenitore.

In genere, l'ordine di tabulazioni predefinito è basato sulla modalità di definizione dei controlli in XAML, in particolare sull'ordine in cui i controlli vengono attraversati dalle utilità per la lettura dello schermo. Tuttavia, l'ordine predefinito non corrisponde necessariamente all'ordine visivo. La posizione di visualizzazione effettiva può dipendere dal contenitore di layout padre e dalle varie proprietà degli elementi figlio che possono influire sul layout.

Per assicurarsi che l'app abbia un ordine di tabulazione ottimale, testare il comportamento manualmente. Se si usa una griglia o una tabella per il layout, l'ordine in cui gli utenti potrebbero leggere lo schermo rispetto all'ordine di tabulazione potrebbe essere molto diverso. Questo non è sempre un problema, ma assicurati di testare le funzionalità della tua app tramite tocco e tastiera per verificare che l'interfaccia utente sia ottimizzata per entrambi i metodi di input.

Puoi fare in modo che l'ordine di tabulazione corrisponda all'ordine visivo modificando il codice XAML o ignorando l'ordine di tabulazione predefinito. Nell'esempio seguente viene illustrato come utilizzare la proprietà TabIndex con un layout Grid che usa lo spostamento tramite tabulazione in base alla colonna.

<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 alcuni casi, è possibile escludere un controllo specifico dall'ordine di tabulazioni. Questa operazione viene in genere eseguita impostando la proprietà IsEnabled su false per rendere il controllo non interattivo. Un controllo disabilitato viene escluso automaticamente dall'ordine di tabulazioni.

Se si desidera escludere un controllo interattivo dall'ordine di tabulazione, è possibile impostare la proprietà IsTabStop su false.

Per impostazione predefinita, gli elementi dell'interfaccia utente che supportano lo stato attivo vengono in genere inclusi nell'ordine di tabulazione. Alcune eccezioni a questo includono alcuni tipi di visualizzazione del testo (ad esempio RichTextBlock) che supportano lo stato attivo per la selezione del testo e l'accesso agli Appunti, ma non sono nell'ordine di tabulazione perché sono elementi di testo statici. Questi controlli non sono convenzionalmente interattivi (non possono essere richiamati e non richiedono input di testo, ma supportano il pattern di controllo Text che supporta la ricerca e la regolazione dei punti di selezione nel testo). I controlli di testo verranno comunque rilevati da assistive technology e letti ad alta voce nelle utilità per la lettura dello schermo, ma che si basano su tecniche diverse dall'ordine di tabulazioni.

Se si modificano i valori TabIndex o si usa l'ordine predefinito, si applicano queste regole:

  • Se TabIndex non è impostato su un elemento, il valore predefinito è Int32.MaxValue e l'ordine di tabulazione si basa sull'ordine di dichiarazione nelle raccolte XAML o figlio.
  • Se TabIndex è impostato su un elemento:
    • Gli elementi dell'interfaccia utente con TabIndex uguale a 0 vengono aggiunte all'ordine di tabulazione in base all'ordine di dichiarazione in XAML o nelle raccolte figlio.
    • Gli elementi dell'interfaccia utente con TabIndex maggiore di 0 vengono aggiunti all'ordine di tabulazioni in base al valore TabIndex.
    • Gli elementi dell'interfaccia utente con TabIndex minore di 0 vengono aggiunte all'ordine di tabulazione e vengono visualizzate prima di qualsiasi valore zero.

Il frammento di codice seguente mostra una raccolta di elementi con varie impostazioni TabIndex (B viene assegnato il valore di Int32.MaxValue o 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>

Ciò si traduce nel seguente ordine di tabulazione:

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

Spostamento tramite tastiera tra i riquadri dell'applicazione con F6

Un riquadro applicazione è un'area logica di interfaccia utente prominente e correlata all'interno di una finestra dell'applicazione( ad esempio, i riquadri di Microsoft Edge includono la barra degli indirizzi, la barra dei segnalibri, la barra delle schede e il pannello del contenuto). Il tasto F6 può essere usato per spostarsi tra questi riquadri, in cui è possibile accedere a gruppi di elementi figlio usando lo spostamento tramite tastiera standard.

Anche se lo spostamento tramite tastiera può fornire un'interfaccia utente conforme ad accesso, per rendere un'interfaccia utente utilizzabile in modo accessibile spesso sono necessari alcuni passaggi aggiuntivi. In genere, ciò include:

  • Ascolto di F6 per spostarsi tra sezioni importanti dell'interfaccia utente.
  • Aggiunta di tasti di scelta rapida per azioni comuni nell'interfaccia utente.
  • Aggiunta di chiavi di accesso a controlli importanti nell'interfaccia utente.

Per altre indicazioni sull'implementazione dei tasti di scelta rapida e dei tasti di scelta rapida, vedere Tasti di scelta rapida di seguito e Tasti di scelta rapida.

Ottimizzare per F6

F6 consente agli utenti di tastiera di spostarsi in modo efficiente tra riquadri dell'interfaccia utente senza tabulazione attraverso potenzialmente centinaia di controlli.

Ad esempio, F6 in Microsoft Edge scorre tra la barra degli indirizzi, la barra dei segnalibri, la barra delle schede e il pannello del contenuto. Poiché una pagina Web può avere potenzialmente centinaia di controlli tabulabili, F6 può rendere più semplice per gli utenti della tastiera raggiungere la barra delle schede e la barra degli indirizzi senza usare tasti di scelta rapida specifici dell'applicazione.

Il ciclo di tabulazioni F6 può anche corrispondere in modo libero a punti di riferimento o intestazioni nel contenuto, anche se non deve corrispondere esattamente. F6 deve concentrarsi su aree di grandi dimensioni e distinte nell'interfaccia utente, mentre i punti di riferimento possono essere più granulari. Ad esempio, è possibile contrassegnare una barra dell'app e la relativa casella di ricerca come punti di riferimento, ma includere solo la barra dell'app stessa nel ciclo F6.

Importante

È necessario implementare lo spostamento F6 nell'app perché non è supportato in modo nativo.

Dove possibile, le aree nel ciclo F6 devono avere un nome accessibile: tramite un punto di riferimento o aggiungendo manualmente un AutomationProperties.Name all'elemento "radice" dell'area.

Maiusc+F6 deve scorrere in direzione opposta.

Spostamento tramite tastiera all'interno di un elemento dell'interfaccia utente

Per i controlli compositi, è importante garantire una corretta navigazione interna tra gli elementi contenuti. Un controllo composito può gestire l'elemento figlio attualmente attivo per ridurre l'overhead di avere tutti gli elementi figlio che supportano lo stato attivo. Il controllo composito è incluso nell'ordine di tabulazioni e gestisce gli eventi di spostamento tramite tastiera stessi. Molti controlli compositi dispongono già di una logica di spostamento interna integrata nella gestione degli eventi. Ad esempio, l'attraversamento con tasti di direzione degli elementi è abilitato per impostazione predefinita nei controlli ListView, GridView, ListBox e FlipView.

Alternative della tastiera alle azioni e agli eventi del puntatore per elementi di controllo specifici

Gli elementi dell'interfaccia utente su cui è possibile fare clic devono anche essere richiamabili tramite la tastiera. Per usare la tastiera con un elemento dell'interfaccia utente, l'elemento deve avere lo stato attivo (solo le classi che derivano da Control supportano lo stato attivo e lo spostamento tramite tabulazione).

Per gli elementi dell'interfaccia utente che possono essere richiamati, implementare i gestori eventi della tastiera per la barra spaziatrice e i tasti INVIO. In questo modo si garantisce il supporto di accessibilità della tastiera di base e consente agli utenti di raggiungere tutti gli elementi interattivi dell'interfaccia utente e attivare la funzionalità usando solo la tastiera.

Se un elemento non supporta lo stato attivo, è possibile creare un controllo personalizzato. In questo caso, per abilitare lo stato attivo, è necessario impostare la proprietà IsTabStop su true e fornire un'indicazione visiva dello stato visivo con un indicatore di stato attivo.

Tuttavia, può essere più semplice usare la composizione dei controlli in modo che il supporto per tabulazioni, stato attivo e Microsoft Automazione interfaccia utente peer e pattern vengano gestiti dal controllo all'interno del quale si sceglie di comporre il contenuto. Ad esempio, invece di gestire un evento premuto dal puntatore su un'immagine, eseguire il wrapping di tale elemento in un pulsante per ottenere il supporto di puntatore, tastiera e stato attivo.

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

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

Scelte rapide da tastiera

Oltre all'implementazione dello spostamento e dell'attivazione della tastiera, è consigliabile implementare tasti di scelta rapida come tasti di scelta rapida e tasti di scelta rapida per funzionalità importanti o usate di frequente.

Un tasto di scelta rapida è una combinazione di tastiera che consente all'utente di accedere alle funzionalità dell'app. Ci sono due tipi di tasti di scelta rapida:

  • Gli acceleratori sono tasti di scelta rapida che richiamano un comando dell'app. La tua app potrebbe offrire o meno un'interfaccia utente specifica che corrisponde al comando. Gli acceleratori sono in genere costituiti dal tasto Ctrl più un tasto lettera.
  • I tasti di accesso rapido sono tasti di scelta rapida che impostano lo stato attivo su un'interfaccia utente specifica nell'applicazione. I tasti di accesso rapido sono costituiti dal tasto Alt e da un tasto lettera.

Fornire sempre un modo semplice per gli utenti che si basano sulle utilità per la lettura dello schermo e altre tecnologie di assistive technology per individuare i tasti di scelta rapida dell'app. Comunicare i tasti di scelta rapida usando descrizioni comandi, nomi accessibili, descrizioni accessibili o altre forme di comunicazione sullo schermo. Come minimo, i tasti di scelta rapida devono essere ben documentati nel contenuto della Guida dell'app.

È possibile documentare i tasti di scelta tramite utilità per la lettura dello schermo impostando la proprietà associata AutomationProperties.AccessKey su una stringa che descrive il tasto di scelta rapida. Esiste anche una proprietà associata AutomationProperties.AcceleratorKey per documentare i tasti di scelta rapida non mnemonici, anche se le utilità per la lettura dello schermo trattano in genere entrambe le proprietà allo stesso modo. Provare a documentare i tasti di scelta rapida in diversi modi, usando descrizioni comando, proprietà di automazione e documentazione della Guida scritta.

Nell'esempio seguente viene illustrato come documentare i tasti di scelta rapida per i pulsanti di riproduzione multimediale, sospensione e arresto.

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

Importante

L'impostazione di AutomationProperties.AcceleratorKey o AutomationProperties.AccessKey non abilita la funzionalità della tastiera. Questo indica solo le chiavi da usare per il framework Automazione interfaccia utente e quindi possono essere passate agli utenti tramite assistive technology.

La gestione delle chiavi viene implementata nel code-behind, non in XAML. Devi comunque collegare i gestori per gli eventi KeyDown o KeyUp sul controllo pertinente per implementare effettivamente il comportamento dei tasti di scelta rapida nella tua app. Inoltre, la decorazione del testo sottolineato per un tasto di scelta non viene fornita automaticamente. È necessario sottolineare in modo esplicito il testo per la chiave specifica nel tasto mnemonico come formattazione sottolineatura inline se si desidera visualizzare il testo sottolineato nell'interfaccia utente.

Per semplicità, l'esempio precedente omette l'uso di risorse per stringhe come "CTRL+A". Tuttavia, è necessario prendere in considerazione anche i tasti di scelta rapida durante la localizzazione. La localizzazione dei tasti di scelta rapida è rilevante perché la scelta del tasto da usare come tasto di scelta rapida dipende in genere dall'etichetta di testo visibile per l'elemento.

Per altre indicazioni sull'implementazione dei tasti di scelta rapida, vedere Tasti di scelta rapida nelle Linee guida per l'interazione dell'esperienza utente di Windows.

Implementazione di un gestore eventi della chiave

Gli eventi di input, ad esempio gli eventi chiave, usano un concetto di evento denominato eventi indirizzati. Un evento indirizzato può scorrere gli elementi figlio di un controllo composito padre, in modo che il controllo padre possa gestire eventi per più elementi figlio. Questo modello di evento è utile per definire le azioni dei tasti di scelta rapida per un controllo che contiene diversi elementi figlio, nessuno dei quali può avere lo stato attivo o far parte dell'ordine di tabulazione.

Ad esempio di codice che mostra come scrivere un gestore eventi di tasti che include il controllo della presenza di modificatori, ad esempio il tasto CTRL, vedere Interazioni con tastiera.

Spostamento tramite tastiera per i controlli personalizzati

È consigliabile usare i tasti di direzione come tasti di scelta rapida per spostarsi tra gli elementi figlio nei casi in cui gli elementi figlio hanno una relazione spaciale tra loro. Se i nodi della visualizzazione albero hanno sottoelementi separati per la gestione dell'attivazione di espansione e compressione dei nodi, usare i tasti freccia sinistra e destra per fornire la funzionalità di espansione della tastiera. Se si dispone di un controllo orientato che supporta l'attraversamento direzionale all'interno del contenuto del controllo, usare i tasti di direzione appropriati.

In genere si implementa la gestione delle chiavi personalizzata per i controlli personalizzati includendo un override dei metodi OnKeyDown e OnKeyUp come parte della logica della classe.

Esempio di stato di visualizzazione per un indicatore di stato attivo

Come accennato in precedenza, qualsiasi controllo personalizzato che supporta lo stato attivo deve avere un indicatore di stato attivo visivo. In genere, l'indicatore di stato attivo è solo un rettangolo che delinea il rettangolo di delimitazione del controllo. Rectangle per lo stato attivo visivo è un elemento peer del resto della composizione del controllo in un modello di controllo, ma inizialmente viene impostato con un valore Visibility di Collapsed perché il controllo non è ancora attivo. Quando il controllo ottiene lo stato attivo, viene richiamato uno stato di visualizzazione che imposta in modo specifico la visibilità dell'oggetto visivo dello stato attivo su Visible. Una volta spostato lo stato attivo altrove, viene chiamato un altro stato di visualizzazione e la proprietà Visibility diventa Collapsed.

Tutti i controlli XAML attivabili visualizzano un indicatore di stato attivo visivo appropriato quando viene attivo. L'utente selezionato può anche influire sull'aspetto dell'indicatore (in particolare se l'utente usa una modalità a contrasto elevato). Se usi i controlli XAML nell'interfaccia utente (e non sostituisci i modelli di controllo), non devi eseguire alcuna operazione aggiuntiva per ottenere indicatori di stato attivo visivi predefiniti. Tuttavia, se intendi ripetere un controllo o se sei curioso di come i controlli XAML forniscono i relativi indicatori di stato attivo visivo, la parte restante di questa sezione spiega come viene eseguita in XAML e nella logica di controllo.

Ecco un esempio di XAML proveniente dal modello XAML predefinito per un pulsante.

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>

Finora questa è solo la composizione. Per controllare la visibilità dell'indicatore di stato attivo, definisci gli stati visivi che attivano o disattivano la proprietà Visibility. Questa operazione viene eseguita usando la proprietà associata VisualStateManager e VisualStateManager.VisualStateGroups, come applicato all'elemento radice che definisce la composizione.

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

Si noti che solo uno degli stati denominati regola direttamente Visibility , mentre gli altri sono apparentemente vuoti. Con gli stati di visualizzazione, non appena il controllo usa un altro stato dello stesso VisualStateGroup, tutte le animazioni applicate dallo stato precedente vengono immediatamente annullate. Poiché il valore predefinito Visibilità dalla composizione è Collapsed, il rettangolo non verrà visualizzato. La logica di controllo controlla questo aspetto ascoltando eventi di stato attivo come GotFocus e modificando gli stati con GoToState. Spesso questo è già gestito automaticamente se si usa un controllo predefinito o si personalizza in base a un controllo che ha già tale comportamento.

Accessibilità tramite tastiera e dispositivi senza una tastiera hardware

Alcuni dispositivi non dispongono di una tastiera hardware dedicata e si basano invece su un pannello SIP (Soft Input Panel). Le utilità per la lettura dello schermo possono leggere l'input di testo dal SIP di testo e gli utenti possono scoprire dove si trovano le dita perché l'utilità per la lettura dello schermo può rilevare che l'utente sta analizzando i tasti e legge ad alta voce il nome della chiave analizzata. Inoltre, alcuni dei concetti di accessibilità orientata alla tastiera possono essere mappati a comportamenti di assistive technology correlati che non usano affatto una tastiera. Ad esempio, anche se un SIP non include un tasto TAB, l'Assistente vocale supporta un movimento tocco equivalente a premere TAB, quindi avere un ordine di tabulazioni utile attraverso i controlli in un'interfaccia utente è ancora crtical per l'accessibilità. L'Assistente vocale supporta anche molti altri movimenti tocco, inclusi i tasti di direzione per spostarsi all'interno di controlli complessi (vedere Comandi della tastiera dell'Assistente vocale e movimenti di tocco).

Esempi

Suggerimento

L'app Raccolta WinUI 3 include esempi interattivi della maggior parte dei controlli e delle funzionalità di WinUI 3. Scaricare l'app da Microsoft Store od ottenere il codice sorgente su GitHub