Input di testo personalizzato

Le API di testo di base nello spazio dei nomi Windows.UI.Text.Core consentono a un'app Windows di ricevere input di testo da qualsiasi servizio di testo supportato sui dispositivi Windows. Le API sono simili alle API del Framework servizi di testo perché non è necessario che abbiano una conoscenza dettagliata dei servizi di testo. In questo modo, l'app può ricevere testo in qualsiasi lingua e da qualsiasi tipo di input, come tastiera, riconoscimento vocale o penna.

API importanti: Windows.UI.Text.Core, CoreTextEditContext

Perché usare le API di testo di base?

Per molte app, i controlli casella di testo XAML o HTML sono sufficienti per l'input di testo e la modifica. Tuttavia, se l'app gestisce scenari di testo complessi, ad esempio un'app di elaborazione di testo, potrebbe essere necessaria la flessibilità di un controllo di modifica del testo personalizzato. È possibile usare le API da tastiera CoreWindow per creare il controllo di modifica del testo, anche se non forniscono un modo per ricevere input di testo basato su composizione, necessario per supportare le lingue dell'Asia orientale.

Usare invece le API Windows.UI.Text.Core quando è necessario creare un controllo di modifica del testo personalizzato. Queste API sono progettate per garantire molta flessibilità nell'elaborazione dell'input di testo, in qualsiasi lingua, e per offrire l'esperienza di testo più adatta all'app. I controlli di input e modifica del testo creati con le API di testo di base possono ricevere input di testo da tutti i metodi di input di testo esistenti sui dispositivi Windows, dagli Input Method Editor (IME) del Framework servizi di testo e dalla scrittura su PC alla tastiera WordFlow (che fornisce correzione automatica, previsione e dettatura) sui dispositivi mobili.

Architettura

Di seguito è riportata una rappresentazione semplice del sistema di input di testo.

  • "Applicazione" rappresenta un'app Windows che ospita un controllo di modifica personalizzato creando usando le API di testo di base.
  • Le API Windows.UI.Text.Core favoriscono la comunicazione con i servizi di testo tramite Windows. La comunicazione tra il controllo di modifica di testo e i servizi di testo viene gestita principalmente tramite un oggetto CoreTextEditContext che fornisce i metodi e gli eventi per favorirla.

CoreText architecture diagram

Selezioni e intervalli di testo

I controlli di modifica forniscono spazio per l'immissione di testo e gli utenti si aspettano di modificare il testo in qualsiasi punto di questo spazio. Qui, spieghiamo il sistema di posizionamento del testo usato dalle API di testo di base e come gli intervalli e le selezioni vengono rappresentati in questo sistema.

Posizione del cursore dell'applicazione

Gli intervalli di testo usati con le API di testo di base sono espressi in termini di posizioni del cursore. "Application Caret Position (ACP)" è un numero con base zero che indica il numero di caratteri dall'inizio del flusso di testo immediatamente prima del cursore, come mostrato qui.

Screenshot showing the Application Caret Position (ACP) count of characters

Selezioni e intervalli di testo

Le selezioni e gli intervalli di testo sono rappresentati dalla struttura CoreTextRange che contiene due campi:

Campo Tipo di dati Descrizione
StartCaretPosition Number [JavaScript] | System.Int32 [.NET] | int32 [C++] La posizione iniziale di un intervallo è l'ACP immediatamente prima del primo carattere.
EndCaretPosition Number [JavaScript] | System.Int32 [.NET] | int32 [C++] La posizione finale di un intervallo è l'ACP immediatamente dopo l'ultimo carattere.

 

Ad esempio, nell'intervallo di testo mostrato in precedenza, l'intervallo [0, 5] specifica la parola "Hello". StartCaretPosition deve essere sempre minore o uguale a EndCaretPosition. L'intervallo [5, 0] non è valido.

Punto di inserimento

La posizione corrente del cursore, spesso definita punto di inserimento, è rappresentata dall'impostazione di StartCaretPosition su un valore uguale a EndCaretPosition.

Selezione non contigua

Alcuni controlli di modifica supportano le selezioni non contigue. Ad esempio, le app Microsoft Office supportano più selezioni arbitrarie e molti editor di codice sorgente supportano la selezione delle colonne. Tuttavia, le API di testo di base non supportano le selezioni non contigue. I controlli di modifica devono riferire solo una singola selezione contigua, spesso l'intervallo secondario attivo delle selezioni non contigue.

Ad esempio, l'immagine seguente mostra un flusso di testo con due selezioni non contigue: [0, 1] e [6, 11] per cui il controllo di modifica deve segnalarne solo uno ([0, 1] o [6, 11]).

Screenshot showing a non-contiguous text selection, where the first character and the last five characters are selected.

Utilizzo del testo

La classe CoreTextEditContext consente il flusso di testo tra Windows e i controlli di modifica attraverso l'evento TextUpdating, l'evento TextRequested e il metodo NotifyTextChanged.

Il controllo di modifica riceve il testo attraverso eventi TextUpdating generati quando gli utenti interagiscono con i metodi di input di testo come tastiere, riconoscimento vocale o IME.

Quando si modifica il testo nel controllo di modifica, ad esempio incollando testo nel controllo, è necessario inviare una notifica a Windows chiamando NotifyTextChanged.

Se il servizio di testo richiede nuovo testo, viene generato un evento TextRequested. È necessario fornire nuovo testo nel gestore dell'evento TextRequested.

Come accettare gli aggiornamenti di testo

Il controllo di modifica deve in genere accettare le richieste di aggiornamento del testo perché rappresentano il testo che l'utente vuole immettere. Nel gestore dell'evento TextUpdating queste azioni sono previste per il controllo di modifica:

  1. Inserire il testo specificato in CoreTextTextUpdatingEventArgs.Text nella posizione specificata in CoreTextTextUpdatingEventArgs.Range.
  2. Posizionare la selezione nella posizione specificata in CoreTextTextUpdatingEventArgs.NewSelection.
  3. Notificare al sistema quando l'aggiornamento viene completato impostando CoreTextTextUpdatingEventArgs.Result su CoreTextTextUpdatingResult.Succeeded.

Ad esempio, questo è lo stato di un controllo di modifica prima che l'utente digiti "d". Il punto di inserimento si trova a [10, 10].

Screenshot of a text stream diagram showing the insertion point at [10, 10], before an insertion

Quando l'utente digita "d", viene generato un evento TextUpdating con i seguenti dati CoreTextTextUpdatingEventArgs:

Nel controllo di modifica applicare le modifiche specificate e impostare Result su Succeeded. Ecco lo stato del controllo dopo l'applicazione delle modifiche.

Screenshot of a text stream diagram showing the insertion point at \[11, 11\], after an insertion

Come rifiutare gli aggiornamenti del testo

In alcuni casi, non è possibile applicare aggiornamenti del testo perché l'intervallo richiesto si trova in un'area del controllo di modifica che non deve essere modificata. In questo caso, non applicare modifiche. Invece, notificare al sistema che l'aggiornamento non è andato a buon fine impostando CoreTextTextUpdatingEventArgs.Result su CoreTextTextUpdatingResult.Failed.

Si consideri, ad esempio, un controllo di modifica che accetta solo un indirizzo e-mail. Gli spazi devono essere rifiutati perché gli indirizzi e-mail non possono contenere spazi, quindi quando vengono generati eventi TextUpdating per la barra spaziatrice, impostare semplicemente Result su Failed nel controllo di modifica.

Notifica delle modifiche di testo

In alcuni casi, il controllo di modifica apporta modifiche al testo, ad esempio quando il testo viene incollato o corretto automaticamente. In questi casi, è necessario notificare ai servizi di testo queste modifiche chiamando il metodo NotifyTextChanged.

Ad esempio, si tratta dello stato di un controllo di modifica prima che l'utente incolli "World". Il punto di inserimento si trova a [6, 6].

Screenshot of a text stream diagram showing the insertion point at [6, 6], before an insertion

L'utente esegue l'azione Incolla e il controllo di modifica dopo l'applicazione delle modifiche:

Screenshot of a text stream diagram showing the insertion point at \[11, 11\], after an insertion

In questo caso, è necessario chiamare NotifyTextChanged con questi argomenti:

  • modifiedRange = [6, 6]
  • newLength = 5
  • newSelection = [11, 11]

Seguiranno uno o più eventi TextRequested, da gestire per aggiornare il testo con cui lavorano i servizi di testo.

Override degli aggiornamenti del testo

Nel controllo di modifica potrebbe essere necessario eseguire l'override di un aggiornamento del testo per fornire funzionalità di correzione automatica.

Si consideri, ad esempio, un controllo di modifica che fornisce una funzionalità di correzione che formalizza le contrazioni. Si tratta dello stato del controllo di modifica prima che l'utente digiti la barra spaziatrice per attivare la correzione. Il punto di inserimento si trova a [3, 3].

Screenshot of a text stream diagram showing the insertion point at [3, 3], before an insertion

L'utente preme la barra spaziatrice e viene generato un evento TextUpdating. Il controllo di modifica accetta l'aggiornamento del testo. Questo è lo stato del controllo di modifica per un breve istante prima che la correzione venga completata. Il punto di inserimento si trova a [4, 4].

Screenshot of a text stream diagram showing the insertion point at [4, 4], after an insertion

All'esterno del gestore dell'evento TextUpdating il controllo di modifica apporta la seguente correzione. Questo è lo stato del controllo di modifica dopo il completamento della correzione. Il punto di inserimento si trova a [5, 5].

Screenshot of a text stream diagram showing the insertion point at [5, 5]

In questo caso, è necessario chiamare NotifyTextChanged con questi argomenti:

  • modifiedRange = [1, 2]
  • newLength = 2
  • newSelection = [5, 5]

Seguiranno uno o più eventi TextRequested, da gestire per aggiornare il testo con cui lavorano i servizi di testo.

Come fornire il testo richiesto

È importante che i servizi di testo dispongano del testo corretto per fornire funzionalità come la previsione o la correzione automatica, soprattutto per il testo già esistente nel controllo di modifica, dal caricamento di un documento o di testo inserito dal controllo di modifica, come illustrato nelle sezioni precedenti. Pertanto, ogni volta che viene generato un evento TextRequested, è necessario fornire il testo presente nel controllo di modifica per l'intervallo specificato.

Talvolta, Range in CoreTextTextRequest specifica un intervallo che il controllo di modifica non può sistemare così com'è. Ad esempio, Range supera le dimensioni del controllo di modifica al momento dell'evento TextRequested oppure la fine di Range è fuori intervallo. In questi casi, è necessario restituire qualsiasi intervallo appropriato, in genere un sottoinsieme dell'intervallo richiesto.

Esempi

Esempi di archivio