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.
Eventi da tastiera e focus
Gli eventi di tastiera seguenti possono verificarsi sia per l'hardware che per le tastiere touch.
| Event | Description |
|---|---|
| KeyDown | Si verifica quando un tasto viene premuto. |
| KeyUp | Si verifica quando si rilascia un tasto. |
Importante
Alcuni controlli XAML gestiscono internamente gli eventi di input. In questi casi potrebbe sembrare che non si verifichi un evento di input perché il listener di eventi non richiama il gestore associato. In genere, questo sottoinsieme di tasti viene elaborato dal gestore della classe per fornire il supporto incorporato dell'accessibilità tramite tastiera di base. Ad esempio, la classe Button esegue l'override degli eventi OnKeyDown sia per la chiave Space che per il tasto Enter (così come OnPointerPressed) e li indirizza all'evento Click del controllo. Quando un tasto premuto viene gestito dalla classe di controllo, gli eventi KeyDown e KeyUp non vengono generati.
Ciò fornisce un equivalente tastiera predefinito per richiamare il pulsante, in modo simile a toccarlo con un dito o facendo clic con un mouse. Le chiavi diverse da Space o Enter attivano comunque gli eventi KeyDown e KeyUp. Per ulteriori informazioni sul funzionamento della gestione degli eventi basata sulle classi (in particolare, la sezione "Gestori di eventi di input nei controlli"), vedere Panoramica degli eventi e degli eventi instradati.
I controlli nella tua interfaccia utente generano eventi da tastiera solo quando hanno il focus di input. Un singolo controllo riceve il focus quando l'utente fa clic o tocca direttamente tale controllo nel layout, oppure preme il tasto TAB per entrare in una sequenza di tabulazione all'interno dell'area del contenuto.
Puoi anche richiamare il metodo Focus di un controllo per impostare forzatamente lo stato attivo. Questo è necessario quando si implementano le scorciatoie da tastiera, perché il focus della tastiera non viene impostato automaticamente quando si carica l'interfaccia utente. Per altre info, vedi l'esempio di tasti di scelta rapida più avanti in questo argomento.
Affinché un controllo riceva il focus di input, deve essere abilitato, visibile e avere le proprietà IsTabStop e HitTestVisible impostate su true. Questo è lo stato predefinito per la maggior parte dei controlli. Quando un controllo ha lo stato attivo per l'input, può generare e rispondere agli eventi di input della tastiera, come descritto più avanti in questo argomento. Puoi anche rispondere a un controllo che riceve o perde lo stato attivo gestendo gli eventi GotFocus e LostFocus.
Per impostazione predefinita, la sequenza di schede dei controlli è l'ordine in cui vengono visualizzati nel linguaggio XAML (Extensible Application Markup Language). Tuttavia, è possibile modificare questo ordine usando la proprietà TabIndex. Per altre info, vedi Implementazione dell'accessibilità da tastiera.
Gestori eventi della tastiera
Un gestore eventi di input implementa un delegato che fornisce le informazioni seguenti:
- Il mittente dell'evento. Il mittente segnala l'oggetto a cui è associato il gestore eventi.
- Dati dell'evento. Per gli eventi della tastiera, tali dati saranno un'istanza di KeyRoutedEventArgs. Il delegato per i gestori è KeyEventHandler. Le proprietà più rilevanti di KeyRoutedEventArgs per la maggior parte degli scenari del gestore sono Key e possibilmente KeyStatus.
- OriginalSource. Poiché gli eventi della tastiera sono eventi instradati, i dati dell'evento includono OriginalSource. Se si lascia deliberatamente che gli eventi si propaghino attraverso una gerarchia di oggetti, OriginalSource a volte è l'oggetto rilevante anziché il mittente. Tuttavia, dipende dalla progettazione. Per altre informazioni su come usare OriginalSource anziché mittente, vedere la sezione "Eventi indirizzati tramite tastiera" di questo argomento o Eventi e panoramica degli eventi indirizzati.
Collegamento di un gestore eventi della tastiera
È possibile allegare le funzioni del gestore eventi della tastiera per qualsiasi oggetto che include l'evento come membro. Ciò include qualsiasi classe derivata UiElement. L'esempio XAML seguente mostra come collegare i gestori per l'evento KeyUp per una griglia.
<Grid KeyUp="Grid_KeyUp">
...
</Grid>
È anche possibile allegare un gestore eventi nel codice. Per altre informazioni, vedi Panoramica degli eventi e degli eventi indirizzati.
Definizione di un gestore eventi della tastiera
Nell'esempio seguente viene illustrata la definizione incompleta del gestore eventi per il gestore eventi KeyUp associato nell'esempio precedente.
void Grid_KeyUp(object sender, KeyRoutedEventArgs e)
{
//handling code here
}
Private Sub Grid_KeyUp(ByVal sender As Object, ByVal e As KeyRoutedEventArgs)
' handling code here
End Sub
void MyProject::MainPage::Grid_KeyUp(
Platform::Object^ sender,
Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
//handling code here
}
Utilizzo di KeyRoutedEventArgs
Tutti gli eventi della tastiera usano KeyRoutedEventArgs per i dati dell'evento e KeyRoutedEventArgs contiene le proprietà seguenti:
- Chiave
- KeyStatus
- Gestito
- OriginalSource (ereditato da RoutedEventArgs)
Chiavi virtuali
L'evento KeyDown viene generato se viene premuto un tasto. Analogamente, KeyUp viene generato se viene rilasciata una chiave. In genere, si ascoltano gli eventi per elaborare un valore di chiave specifico. Per determinare quale tasto viene premuto o rilasciato, controllare il valore chiave nei dati dell'evento. Key restituisce un valore VirtualKey . L'enumerazione VirtualKey include tutte le chiavi supportate.
Tasti di modifica
I tasti di modifica sono tasti come CTRL o MAIUSC che in genere gli utenti usano in combinazione con altri tasti. L'app può usare queste combinazioni come tasti di scelta rapida personalizzati per richiamare i comandi dell'app.
Annotazioni
Per le scelte rapide da tastiera predefinite, vedi Tasti di scelta e Scelte rapide da tastiera.
È possibile rilevare le combinazioni di tasti di scelta rapida nei gestori eventi KeyDown e KeyUp. Quando si verifica un evento della tastiera per un tasto non modificatore, è possibile controllare se un tasto di modifica è nello stato premuto.
In alternativa, in WinUI 3 puoi usare InputKeyboardSource.GetKeyStateForCurrentThread per controllare lo stato del modificatore quando viene premuto un tasto non modificatore.
Gli esempi seguenti implementano questo secondo metodo, includendo anche il codice stub per la prima implementazione.
Annotazioni
Il tasto ALT è rappresentato dal valore VirtualKey.Menu .
Esempio di combinazioni di tasti
Nell'esempio seguente viene illustrato come implementare un set di tasti di scelta rapida personalizzati. In questo esempio, gli utenti possono controllare la riproduzione multimediale usando i pulsanti Riproduci, Sospendi e Arresta oppure CTRL+P, CTRL+A e tasti di scelta rapida ctrl+S. Il codice XAML del pulsante mostra i tasti di scelta rapida utilizzando le descrizioni comando e le proprietà AutomationProperties nelle etichette del pulsante. Questa auto-documentazione è importante per aumentare l'usabilità e l'accessibilità dell'app. Per altre informazioni, vedere Accessibilità tramite tastiera.
Si noti anche che la pagina imposta il focus di input su se stessa quando viene caricata. Senza questo passaggio, nessun controllo ha inizialmente il focus di input e l'app non genera eventi di input finché l'utente non imposta manualmente il focus di input (ad esempio, passando a un controllo con il tasto TAB o facendovi clic).
<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>
//showing implementations but not header definitions
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
(void) e; // Unused parameter
this->Loaded+=ref new RoutedEventHandler(this,&MainPage::ProgrammaticFocus);
}
void MainPage::ProgrammaticFocus(Object^ sender, RoutedEventArgs^ e)
{
this->Focus(Windows::UI::Xaml::FocusState::Programmatic);
}
void KeyboardSupport::MainPage::MediaButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FrameworkElement^ fe = safe_cast<FrameworkElement^>(sender);
if (fe->Name == "PlayButton") {DemoMovie->Play();}
if (fe->Name == "PauseButton") {DemoMovie->Pause();}
if (fe->Name == "StopButton") {DemoMovie->Stop();}
}
bool KeyboardSupport::MainPage::IsCtrlKeyPressed()
{
auto ctrlState = Microsoft::UI::Input::InputKeyboardSource::GetKeyStateForCurrentThread(VirtualKey::Control);
return (ctrlState & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down;
}
void KeyboardSupport::MainPage::Grid_KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true;
}
void KeyboardSupport::MainPage::Grid_KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
if (IsCtrlKeyPressed())
{
if (e->Key==VirtualKey::P) { DemoMovie->Play(); }
if (e->Key==VirtualKey::A) { DemoMovie->Pause(); }
if (e->Key==VirtualKey::S) { DemoMovie->Stop(); }
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Set the input focus to ensure that keyboard events are raised.
this.Loaded += delegate { this.Focus(FocusState.Programmatic); };
}
private void MediaButton_Click(object sender, RoutedEventArgs e)
{
switch ((sender as Button).Name)
{
case "PlayButton": DemoMovie.Play(); break;
case "PauseButton": DemoMovie.Pause(); break;
case "StopButton": DemoMovie.Stop(); break;
}
}
private static bool IsCtrlKeyPressed()
{
var ctrlState = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control);
return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
}
private void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (IsCtrlKeyPressed())
{
switch (e.Key)
{
case VirtualKey.P: DemoMovie.Play(); break;
case VirtualKey.A: DemoMovie.Pause(); break;
case VirtualKey.S: DemoMovie.Stop(); break;
}
}
}
Private isCtrlKeyPressed As Boolean
Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
End Sub
Private Function IsCtrlKeyPressed As Boolean
Dim ctrlState As CoreVirtualKeyStates = Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control);
Return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
End Function
Private Sub Grid_KeyDown(sender As Object, e As KeyRoutedEventArgs)
If IsCtrlKeyPressed() Then
Select Case e.Key
Case Windows.System.VirtualKey.P
DemoMovie.Play()
Case Windows.System.VirtualKey.A
DemoMovie.Pause()
Case Windows.System.VirtualKey.S
DemoMovie.Stop()
End Select
End If
End Sub
Private Sub MediaButton_Click(sender As Object, e As RoutedEventArgs)
Dim fe As FrameworkElement = CType(sender, FrameworkElement)
Select Case fe.Name
Case "PlayButton"
DemoMovie.Play()
Case "PauseButton"
DemoMovie.Pause()
Case "StopButton"
DemoMovie.Stop()
End Select
End Sub
Annotazioni
L'impostazione di AutomationProperties.AcceleratorKey o AutomationProperties.AccessKey in XAML fornisce informazioni sulla stringa, che documenta il tasto di scelta rapida per richiamare tale azione specifica. Le informazioni vengono acquisite dai client Microsoft Automazione interfaccia utente, come Assistente vocale, e sono in genere fornite direttamente all'utente.
L'impostazione di AutomationProperties.AcceleratorKey o AutomationProperties.AccessKey non ha alcuna azione da sola. Dovrai comunque associare i gestori agli eventi KeyDown o KeyUp per implementare effettivamente il comportamento delle scorciatoie da tastiera nella tua app. Inoltre, la sottolineatura del testo per un tasto di accesso non viene applicata automaticamente. È necessario sottolineare esplicitamente il testo del tasto specifico nella sequenza mnemonica utilizzando la formattazione inline Underline se si desidera visualizzare il testo sottolineato nell'interfaccia utente.
Eventi indirizzati tramite tastiera
Alcuni eventi sono eventi indirizzati, tra cui KeyDown e KeyUp. Gli eventi instradati usano la strategia di routing bubbling. La strategia di instradamento a propagazione ascendente significa che un evento ha origine in un oggetto figlio e viene quindi instradato verso i successivi oggetti padre nella gerarchia degli oggetti. Ciò offre un'altra opportunità per gestire lo stesso evento e interagire con gli stessi dati dell'evento.
Si consideri l'esempio XAML seguente, che gestisce gli eventi KeyUp per un oggetto Canvas e due oggetti Button. In questo caso, se si rilascia un tasto mentre il focus è su uno degli oggetti Button, viene generato l'evento KeyUp. L'evento viene quindi propagato al Canvas padre.
<StackPanel KeyUp="StackPanel_KeyUp">
<Button Name="ButtonA" Content="Button A"/>
<Button Name="ButtonB" Content="Button B"/>
<TextBlock Name="statusTextBlock"/>
</StackPanel>
L'esempio seguente illustra come implementare il gestore eventi KeyUp per il contenuto XAML corrispondente nell'esempio precedente.
void StackPanel_KeyUp(object sender, KeyRoutedEventArgs e)
{
statusTextBlock.Text = String.Format(
"The key {0} was pressed while focus was on {1}",
e.Key.ToString(), (e.OriginalSource as FrameworkElement).Name);
}
Si noti l'uso della proprietà OriginalSource nel gestore precedente. In questo caso, OriginalSource segnala l'oggetto che ha generato l'evento. L'oggetto non può essere StackPanel perché StackPanel non è un controllo e non può avere lo stato attivo. Solo uno dei due pulsanti all'interno di StackPanel potrebbe aver generato l'evento, ma quale? Si usa OriginalSource per distinguere l'oggetto origine evento effettivo, se si gestisce l'evento in un oggetto padre.
Proprietà Handled nei dati dell'evento
A seconda della strategia di gestione degli eventi, potrebbe essere necessario che un solo gestore eventi reagisca a un evento di bubbling. Ad esempio, se si dispone di un gestore KeyUp specifico collegato a uno dei controlli Button, avrebbe la prima opportunità di gestire tale evento. In questo caso, potresti non volere che anche il pannello padre gestisca l'evento. Per questo scenario, è possibile usare la proprietà Handled nei dati dell'evento.
Lo scopo della proprietà Handled in una classe di dati di evento indirizzata consiste nel segnalare che un altro gestore registrato in precedenza nella route dell'evento ha già agito. Ciò influisce sul comportamento del sistema di eventi indirizzato. Quando si imposta Handled su true in un gestore eventi, l'evento interrompe il routing e non viene inviato agli elementi padre successivi.
AddHandler ed eventi della tastiera già gestiti
È possibile usare una tecnica speciale per associare gestori che possono agire sugli eventi già contrassegnati come gestiti. Questa tecnica usa il metodo AddHandler per registrare un gestore, anziché usare attributi XAML o sintassi specifica del linguaggio per l'aggiunta di gestori, ad esempio += in C#.
Una limitazione generale di questa tecnica è che l'API AddHandler accetta un parametro di tipo RoutedEvent che identifica l'evento indirizzato in questione. Non tutti gli eventi indirizzati forniscono un identificatore RoutedEvent e questa considerazione influisce quindi sugli eventi indirizzati che possono comunque essere gestiti nel caso Handled. Gli eventi KeyDown e KeyUp hanno indirizzato identificatori di evento (KeyDownEvent e KeyUpEvent) in UIElement. Tuttavia, altri eventi come TextBox.TextChanged non hanno identificatori di evento indirizzati e pertanto non possono essere usati con la tecnica AddHandler.
Sovrascrittura degli eventi e del comportamento della tastiera
È possibile eseguire l'override degli eventi chiave per controlli specifici (ad esempio GridView) per fornire uno spostamento dello stato attivo coerente per vari dispositivi di input, tra cui tastiera e game pad.
Nell'esempio seguente, sottoclassiamo il controllo ed eseguiamo l'override del comportamento KeyDown per spostare lo stato attivo sul contenuto gridView quando viene premuto un tasto freccia.
public class CustomGridView : GridView
{
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
// Override arrow key behaviors.
if (e.Key != Windows.System.VirtualKey.Left && e.Key !=
Windows.System.VirtualKey.Right && e.Key !=
Windows.System.VirtualKey.Down && e.Key !=
Windows.System.VirtualKey.Up)
base.OnKeyDown(e);
else
FocusManager.TryMoveFocus(FocusNavigationDirection.Down);
}
}
Annotazioni
Se si usa un controllo GridView solo per il layout, è consigliabile usare altri controlli, ad esempio ItemsControl con ItemsWrapGrid.
Esecuzione di comandi
Un numero ridotto di elementi dell'interfaccia utente fornisce il supporto predefinito per il comando. L'esecuzione di comandi usa eventi indirizzati correlati all'input nell'implementazione sottostante. Consente di elaborare l'input dell'interfaccia utente associato, ad esempio una determinata azione del puntatore o un tasto di scelta rapida specifico, tramite la chiamata di un unico gestore di comandi.
Se il comando è disponibile per un elemento dell'interfaccia utente, è consigliabile usare le API di comando anziché gli eventi di input discreti. Per altre info, vedi ButtonBase.Command.
È anche possibile implementare ICommand per incapsulare la funzionalità di comando che si richiama dai gestori eventi ordinari. In questo modo è possibile usare i comandi anche quando non è disponibile alcuna proprietà Command .
Immissione di testo e controlli
Alcuni controlli reagiscono agli eventi da tastiera gestendoli autonomamente. Ad esempio, TextBox è un controllo progettato per acquisire e quindi rappresentare visivamente il testo immesso tramite la tastiera. Usa KeyUp e KeyDown nella propria logica per acquisire le sequenze di tasti, quindi genera anche il proprio evento TextChanged se il testo è stato effettivamente modificato.
In genere è comunque possibile aggiungere gestori per KeyUp e KeyDown a un controllo TextBox o a qualsiasi controllo correlato destinato all'elaborazione dell'input di testo. Tuttavia, come parte della progettazione prevista, un controllo potrebbe non rispondere a tutti i valori chiave indirizzati a esso tramite eventi chiave. Il comportamento è specifico di ogni controllo.
Ad esempio, ButtonBase (la classe base per Button) elabora KeyUp in modo che possa verificare la presenza della barra spaziatrice o invio. ButtonBase considera KeyUp equivalente alla pressione del pulsante sinistro del mouse ai fini della generazione di un evento Click. Questa elaborazione dell'evento viene eseguita quando ButtonBase esegue l'override del metodo virtuale OnKeyUp. Nell'implementazione imposta Handled su true. Il risultato è che qualsiasi elemento padre di un pulsante in ascolto di un evento chiave, nel caso di una barra spaziatrice, non riceve l'evento già gestito per i propri gestori.
Un altro esempio è TextBox. Alcuni tasti, ad esempio i tasti di direzione, non sono considerati testo da TextBox e sono invece considerati specifici del comportamento dell'interfaccia utente del controllo. La TextBox contrassegna questi casi di evento come gestiti.
I controlli personalizzati possono implementare un comportamento di override simile per gli eventi chiave eseguendo l'override di OnKeyDown / OnKeyUp. Se il controllo personalizzato elabora specifici tasti di accelerazione o presenta un comportamento del controllo o del focus simile allo scenario descritto per TextBox, si dovrebbe inserire questa logica negli override di OnKeyDown / OnKeyUp.
La tastiera virtuale
I controlli input di testo forniscono supporto automatico per la tastiera virtuale. Quando l'utente porta lo stato attivo su un campo di testo tramite tocco, la tastiera virtuale viene visualizzata automaticamente. Quando il focus di input non è su un campo di testo, la tastiera virtuale viene nascosta.
Quando viene visualizzata la tastiera virtuale, l'interfaccia utente viene automaticamente riposizionata in modo che l'elemento attivo rimanga visibile. Ciò può far sì che altre aree importanti della tua interfaccia utente escano dallo schermo. Tuttavia, puoi disabilitare il comportamento predefinito e apportare modifiche personalizzate all'interfaccia utente quando viene visualizzata la tastiera virtuale. Per altre info, vedi l'esempio di tastiera virtuale.
Se si crea un controllo personalizzato che richiede l'input di testo, ma non deriva da un controllo di input di testo standard, è possibile aggiungere il supporto della tastiera virtuale implementando i pattern di controllo Automazione interfaccia utente corretti. Per altre info, vedi l'esempio di tastiera virtuale.
I tasti premuti sulla tastiera virtuale generano eventi KeyDown e KeyUp proprio come i tasti premuti sulle tastiere hardware. Tuttavia, la tastiera virtuale non genererà eventi di input per CTRL+A, CTRL+Z, CTRL+X, CTRL+C e CTRL+V, che sono riservati per la manipolazione del testo nel controllo di input.
È possibile facilitare e velocizzare notevolmente l'immissione dei dati nell'app impostando l'ambito di input del controllo di testo in base al tipo di dati che si prevede che l'utente immetta. Il campo di input fornisce un'indicazione sul tipo di testo da immettere previsto dal controllo, in modo che il sistema possa fornire un layout specifico della tastiera virtuale per il tipo di input. Ad esempio, se una casella di testo viene usata solo per immettere un PIN di 4 cifre, imposta la proprietà InputScope su Number. In questo modo dai indicazione al sistema di mostrare il layout con il tastierino numerico, che rende più semplice l'immissione del PIN da parte dell'utente. Per ulteriori dettagli, vedere Usare l'ambito di input per modificare la tastiera virtuale.
Articoli correlati
Gli sviluppatori
- Interazioni tramite tastiera
- Identificare i dispositivi di input
- Rispondi alla presenza della tastiera touch
Designer
Samples
- esempio di tastiera touch
- Esempio di input di base
- Esempio di input a bassa latenza
- esempio di elementi visivi di messa a fuoco