Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Utilizza la navigazione con focus per offrire esperienze di interazione complete e coerenti nelle tue app di Windows e nei controlli personalizzati per gli utenti esperti di tastiera, quelli con disabilità e altri requisiti di accessibilità, nonché l'esperienza vista da 3 metri di schermi televisivi e Xbox One.
Informazioni generali
La navigazione tramite stato attivo si riferisce al meccanismo sottostante che consente agli utenti di navigare e interagire con l'interfaccia utente di un'applicazione Windows usando una tastiera, un gamepad o un telecomando.
Annotazioni
I dispositivi di input vengono in genere classificati come dispositivi di puntamento, ad esempio tocco, touchpad, penna e mouse e dispositivi non puntabili, ad esempio tastiera, game pad e telecomando.
Questo argomento descrive come ottimizzare un'applicazione Windows e creare esperienze di interazione personalizzate per gli utenti che si basano su tipi di input non puntanti.
Anche se ci concentriamo sull'input da tastiera per i controlli personalizzati nelle app di Windows nei PC, un'esperienza di tastiera ben progettata è importante anche per le tastiere software come la tastiera virtuale e la tastiera su schermo (OSK), supportando strumenti di accessibilità come l'Assistente vocale di Windows e supportare l'esperienza a 10 piedi.
Vedi Gestire l'input del puntatore per indicazioni sulla creazione di esperienze personalizzate nelle applicazioni Windows per i dispositivi di puntamento.
Per informazioni più generali sulla creazione di app ed esperienze per la tastiera, vedi Interazione con la tastiera.
Linee guida generali
Solo gli elementi dell'interfaccia utente che richiedono l'interazione dell'utente devono supportare la messa a fuoco durante la navigazione. Gli elementi che non richiedono un'azione, come le immagini statiche, non necessitano del focus della tastiera. Le utilità per la lettura dello schermo e gli strumenti di accessibilità simili annunciano ancora questi elementi statici, anche quando non sono inclusi nella navigazione messa a fuoco.
È importante ricordare che, a differenza della navigazione con un dispositivo di puntamento, come un mouse o un dispositivo touch, la navigazione dello stato attivo è lineare. Quando si implementa la navigazione a fuoco, bisogna considerare come un utente interagirà con la tua applicazione e quale dovrebbe essere la navigazione logica. Nella maggior parte dei casi, è consigliabile che il comportamento personalizzato di navigazione del focus segua il modello di lettura preferito della cultura dell'utente.
Altre considerazioni sulla navigazione dello stato attivo includono:
- I controlli sono raggruppati logicamente?
- Esistono gruppi di controlli con maggiore importanza?
- In caso affermativo, questi gruppi contengono sottogruppi?
- Il layout richiede una navigazione direzionale personalizzata (tasti freccia) e un ordine di tabulazione?
L'eBook Engineering Software for Accessibility ha un ottimo capitolo sulla progettazione della gerarchia logica.
Spostamento direzionale 2D per la tastiera
L'area di navigazione interna 2D di un controllo, o di un gruppo di controlli, è definita "area direzionale". Quando il focus passa a questo oggetto, i tasti di direzione della tastiera (sinistra, destra, su e giù) possono essere usati per spostarsi tra gli elementi figlio nell'area di navigazione.
2D Area di navigazione interna, o area direzionale, di un gruppo di controlli
È possibile utilizzare la proprietà XYFocusKeyboardNavigation (con valori possibili di Auto, Enabled o Disabled) per gestire lo spostamento interno 2D con i tasti di direzione della tastiera.
Annotazioni
L'ordine di tabulazione non è influenzato da questa proprietà. Per evitare un'esperienza di navigazione confusa, è consigliabile non specificare in modo esplicito gli elementi figlio di un'area direzionale nell'ordine di navigazione tramite tabulazione dell'applicazione. Per altre informazioni sul comportamento di tabulazione per un elemento, vedi le proprietà UIElement.TabFocusNavigation e TabIndex .
Auto (comportamento predefinito)
Se impostato su Auto, il comportamento di spostamento direzionale è determinato dalla gerarchia di ereditarietà o dall'origine dell'elemento. Se tutti gli antenati sono in modalità predefinita (impostata su Auto), la navigazione direzionale con la tastiera non è supportata.
Disattivato
Impostare XYFocusKeyboardNavigation su Disabled per bloccare lo spostamento direzionale sul controllo e sui relativi elementi figlio.
Comportamento disabilitato di XYFocusKeyboardNavigation
In questo esempio, l'oggetto StackPanel primario (ContainerPrimary) ha XYFocusKeyboardNavigation impostato su Enabled. Tutti gli elementi figlio ereditano questa impostazione e possono essere spostati con i tasti di direzione. Tuttavia, gli elementi B3 e B4 si trovano in uno StackPanel secondario (ContainerSecondary) con XYFocusKeyboardNavigation impostato su Disabled, che esegue l'override del contenitore primario e disabilita lo spostamento dei tasti di direzione su se stesso e tra i relativi elementi figlio.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="75"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
XYFocusKeyboardNavigation="Enabled"
KeyDown="ContainerPrimary_KeyDown"
Orientation="Horizontal"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus" />
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus" />
<StackPanel Name="ContainerSecondary"
XYFocusKeyboardNavigation="Disabled"
Orientation="Horizontal"
BorderBrush="Red"
BorderThickness="2">
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus" />
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus" />
</StackPanel>
</StackPanel>
</Grid>
abilitato
Impostare XYFocusKeyboardNavigation su Enabled per supportare lo spostamento direzionale 2D su un controllo e su ognuno dei relativi oggetti figlio UIElement .
Se impostata, lo spostamento con i tasti di direzione è limitato agli elementi all'interno dell'area direzionale. La navigazione tramite tabulazione non è influenzata, poiché tutti i controlli rimangono accessibili attraverso la loro gerarchia dei tabulazioni.
Comportamento abilitato per XYFocusKeyboardNavigation
In questo esempio, l'oggetto StackPanel primario (ContainerPrimary) ha XYFocusKeyboardNavigation impostato su Enabled. Tutti gli elementi figlio ereditano questa impostazione e possono essere spostati con i tasti di direzione. Gli elementi B3 e B4 si trovano in un oggetto StackPanel secondario (ContainerSecondary) in cui XYFocusKeyboardNavigation non è impostato, che eredita quindi l'impostazione del contenitore primario. L'elemento B5 non si trova all'interno di un'area direzionale dichiarata e non supporta lo spostamento con tasti di direzione, ma supporta il comportamento di spostamento tramite tabulazione standard.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Center">
<StackPanel Name="ContainerPrimary"
XYFocusKeyboardNavigation="Enabled"
KeyDown="ContainerPrimary_KeyDown"
Orientation="Horizontal"
BorderBrush="Green"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus" Margin="5" />
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus" />
<StackPanel Name="ContainerSecondary"
Orientation="Horizontal"
BorderBrush="Red"
BorderThickness="2"
Margin="5">
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5" />
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5" />
</StackPanel>
</StackPanel>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5" />
</StackPanel>
</Grid>
È possibile avere più livelli di aree direzionali annidate. Se tutti gli elementi padre hanno XYFocusKeyboardNavigation impostato su Enabled, i limiti dell'area di spostamento interna vengono ignorati.
Ecco un esempio di due aree direzionali annidate all'interno di un elemento che non supporta in modo esplicito lo spostamento direzionale 2D. In questo caso, lo spostamento direzionale non è supportato tra le due aree annidate.
XYFocusKeyboardNavigation abilitato e comportamento annidato
Ecco un esempio più complesso di tre aree direzionali annidate in cui:
- Quando B1 ha lo stato attivo, solo B5 può essere spostato su (e viceversa) perché esiste un limite di area direzionale in cui XYFocusKeyboardNavigation è impostato su Disabled, rendendo B2, B3 e B4 non raggiungibile con i tasti di direzione
- Quando B2 ha lo stato attivo, solo B3 può essere spostato su (e viceversa) perché il limite dell'area direzionale impedisce lo spostamento del tasto freccia a B1, B4 e B5
- Quando B4 ha lo stato attivo, è necessario usare il tasto Tab per spostarsi tra i controlli
XYFocusKeyboardNavigation attivato e comportamento annidato complesso
Spostamento nelle schede
Anche se i tasti di direzione possono essere usati per lo spostamento direzionale 2D di un controllo o un gruppo di controlli, è possibile usare il tasto TAB per spostarsi tra tutti i controlli in un'applicazione Windows.
Tutti i controlli interattivi supportano lo spostamento tramite tasto TAB per impostazione predefinita (la proprietà IsEnabled e IsTabStop sono true), con l'ordine di tabulazione logico derivato dal layout del controllo nell'applicazione. Tuttavia, l'ordine predefinito non corrisponde necessariamente all'ordine visivo. La posizione di visualizzazione effettiva può dipendere dal contenitore di layout padre e da determinate proprietà che è possibile impostare sugli elementi figlio per influenzare il layout.
Evitare un ordine di tabulazione personalizzato che fa spostare il focus in modo disordinato nell'applicazione. Ad esempio, un elenco di controlli in una maschera deve avere un ordine di tabulazione che passa dall'alto verso il basso e da sinistra a destra (a seconda delle impostazioni locali).
In questa sezione viene descritto come questo ordine di tabulazioni può essere completamente personalizzato in base all'app.
Impostare il comportamento di navigazione con il tasto Tab
La proprietà TabFocusNavigation di UIElement specifica il comportamento di spostamento tramite tabulazione per l'intero albero di oggetti (o area direzionale).
Annotazioni
Utilizzare questa proprietà anziché la proprietà Control.TabNavigation per gli oggetti che non utilizzano un Oggetto ControlTemplate per definirne l'aspetto.
Come accennato nella sezione precedente, per evitare un'esperienza di navigazione confusa, è consigliabile che gli elementi figlio di un'area direzionale non vengano specificati in modo esplicito nell'ordine di navigazione tramite tab dell'applicazione. Per altre informazioni sul comportamento di tabulazione per un elemento, vedere UIElement.TabFocusNavigation e le proprietà TabIndex .
Per le versioni precedenti a Windows 10 Creators Update (build 10.0.15063), le impostazioni delle schede erano limitate agli oggetti ControlTemplate . Per altre info, vedi Control.TabNavigation.
TabFocusNavigation ha un valore di tipo KeyboardNavigationMode con i valori possibili seguenti (si noti che questi esempi non sono gruppi di controlli personalizzati e non richiedono lo spostamento interno con i tasti di direzione):
Gli indici delle tabulazioni locali (impostazione predefinita) vengono riconosciuti nel sottoalbero locale all'interno del contenitore. Per questo esempio, l'ordine di tabulazioni è B1, B2, B3, B4, B5, B6, B7, B1.
Comportamento della scheda "Locale"
Una volta Il contenitore e tutti gli elementi figlio ricevono lo stato attivo una sola volta. Per questo esempio, l'ordine di tabulazioni è B1, B2, B7, B1 (viene illustrato anche lo spostamento interno con tasto freccia).
Comportamento di navigazione tramite tab "una volta"
Ciclo
Lo stato attivo torna all'elemento focalizzabile iniziale all'interno di un contenitore. Per questo esempio, l'ordine di tabulazioni è B1, B2, B3, B4, B5, B6, B2...
Comportamento di navigazione tramite tab "Cycle"
Ecco il codice per gli esempi precedenti (con TabFocusNavigation ="Cycle").
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
KeyDown="Container_KeyDown"
Orientation="Horizontal"
HorizontalAlignment="Center"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<StackPanel Name="ContainerSecondary"
KeyDown="Container_KeyDown"
XYFocusKeyboardNavigation="Enabled"
TabFocusNavigation ="Cycle"
Orientation="Vertical"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
<Button Name="B7"
Content="B7"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
</Grid>
TabIndex
Usare TabIndex per specificare l'ordine in cui gli elementi ricevono lo stato attivo quando l'utente passa attraverso i controlli usando il tasto TAB. Un elemento di controllo con un indice di tabulazione inferiore ottiene lo stato attivo prima di un elemento di controllo con un indice superiore.
Quando un controllo non ha specificato tabIndex , viene assegnato un valore di indice superiore al valore di indice più alto corrente (e la priorità più bassa) di tutti i controlli interattivi nella struttura ad albero visuale, in base all'ambito.
Tutti gli elementi figlio di un controllo sono considerati un ambito e, se uno di questi elementi ha anche elementi figlio, formano un altro ambito. Qualsiasi ambiguità viene risolta scegliendo il primo elemento nella struttura ad albero visuale dell'ambito.
Per escludere un controllo dall'ordine di tabulazione, impostare la proprietà IsTabStop su false.
Eseguire l'override dell'ordine di tabulazioni predefinito impostando la proprietà TabIndex .
Annotazioni
TabIndex funziona allo stesso modo con UIElement.TabFocusNavigation e Control.TabNavigation.
In questo caso viene illustrato come la navigazione del focus può essere influenzata dalla proprietà TabIndex su elementi specifici.
Navigazione nella scheda "Locale" con comportamento di TabIndex
Nell'esempio precedente sono presenti due ambiti:
- B1, area direzionale (B2 - B6) e B7
- area direzionale (B2 - B6)
Quando B3 (nell'area direzionale) ottiene lo stato attivo, l'ambito cambia e lo spostamento tramite tabulazione passa all'area direzionale in cui viene identificato il candidato migliore per lo stato attivo successivo. In questo caso, B2 seguito da B4, B5 e B6. L'ambito cambia di nuovo e l'attenzione si sposta su B1.
Ecco il codice per questo esempio.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
KeyDown="Container_KeyDown"
Orientation="Horizontal"
HorizontalAlignment="Center"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
TabIndex="1"
ToolTipService.ToolTip="TabIndex = 1"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<StackPanel Name="ContainerSecondary"
KeyDown="Container_KeyDown"
TabFocusNavigation ="Local"
Orientation="Vertical"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
TabIndex="3"
ToolTipService.ToolTip="TabIndex = 3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
<Button Name="B7"
Content="B7"
TabIndex="2"
ToolTipService.ToolTip="TabIndex = 2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
</Grid>
Spostamento direzionale 2D per tastiera, game pad e telecomando
Tipi di input non puntatore, ad esempio tastiera, game pad, telecomando e strumenti di accessibilità come Assistente vocale di Windows, condividono un meccanismo comune e sottostante per spostarsi e interagire con l'interfaccia utente dell'applicazione Windows.
In questa sezione viene illustrato come specificare una strategia di spostamento preferita e ottimizzare lo spostamento dello stato attivo all'interno dell'applicazione tramite un set di proprietà della strategia di spostamento che supportano tutti i tipi di input non puntatore basati sullo stato attivo.
Per informazioni più generali sulla creazione di app ed esperienze per Xbox/TV, vedi Interazione da tastiera, progettazione per Xbox e TV e interazioni con game pad e telecomando.
Strategie di spostamento
Le strategie di spostamento sono applicabili a tastiera, game pad, telecomando e vari strumenti di accessibilità.
Le proprietà seguenti della strategia di spostamento consentono di influenzare quale controllo riceve il focus in base al tasto freccia, al pulsante direzionale (D-pad) o a tasti simili premuti.
- XYFocusUpNavigationStrategy
- XYFocusDownNavigationStrategy
- XYFocusLeftNavigationStrategy
- XYFocusRightNavigationStrategy
Queste proprietà hanno valori possibili di Auto (impostazione predefinita), NavigationDirectionDistance, Projection o RectilinearDistance .
Se impostato su Auto, il comportamento dell'elemento si basa sui predecessori dell'elemento. Se tutti gli elementi sono impostati su Auto, viene usata la proiezione .
Annotazioni
Altri fattori, ad esempio l'elemento con stato attivo in precedenza o la prossimità all'asse della direzione di spostamento, possono influenzare il risultato.
Projection
La strategia di proiezione sposta lo stato attivo sul primo elemento rilevato quando il bordo dell'elemento attualmente attivo viene proiettato nella direzione di navigazione.
In questo esempio ogni direzione di spostamento dello stato attivo è impostata su Proiezione. Si noti come l'attenzione si sposta verso il basso da B1 a B4, ignorando B3. Ciò è dovuto al fatto che B3 non si trova nella zona di proiezione. Si noti anche come un candidato di messa a fuoco non venga identificato quando ci si muove a sinistra da B1. Ciò è dovuto al fatto che la posizione di B2 rispetto a B1 elimina B3 come candidato. Se B3 si trovasse nella stessa riga di B2, sarebbe un candidato valido per la navigazione a sinistra. B2 è un candidato valido a causa della sua prossimità non ostruita all'asse della direzione di navigazione.
Strategia di navigazione di proiezione
DistanzaDiDirezioneDiNavigazione
La strategia NavigationDirectionDistance sposta lo stato attivo sull'elemento più vicino all'asse della direzione di navigazione.
Il bordo del rettangolo di delimitazione corrispondente alla direzione di navigazione viene esteso e proiettato per identificare gli obiettivi candidati. Il primo elemento rilevato viene identificato come destinazione. Nel caso di più candidati, l'elemento più vicino viene identificato come obiettivo. Se sono ancora presenti più candidati, l'elemento più alto/sinistro viene identificato come candidato.
Strategia di navigazione NavigationDirectionDistance
Distanza Rettilinea
La strategia RectilinearDistance sposta l'attenzione sull'elemento più vicino in base alla distanza rettilinea 2D (geometria taxicab).
La somma della distanza primaria e della distanza secondaria per ogni potenziale candidato viene usata per identificare il candidato ottimale. In un legame, il primo elemento a sinistra viene selezionato se la direzione richiesta è rivolta verso l'alto o verso il basso e il primo elemento in alto viene selezionato se la direzione richiesta è sinistra o destra.
Strategia di navigazione RectilinearDistance
Questa immagine mostra come, quando B1 ha lo stato attivo e il basso è la direzione richiesta, B3 è il candidato dello stato attivo RectilinearDistance. Questo è basato sui calcoli seguenti per questo esempio:
- Distance (B1, B3, Down) è 10 + 0 = 10
- Distance (B1, B2, Down) è 0 + 40 = 30
- Distance (B1, D, Down) è 30 + 0 = 30
Articoli correlati
- Navigazione del focus a livello di codice
- Interazioni tramite tastiera
- accessibilità tramite tastiera