Dela via


Anpassad textinmatning

Api:erna för kärntext i namnområdet Windows.UI.Text.Core gör att en Windows-app kan ta emot textindata från alla texttjänster som stöds på Windows-enheter. API:erna liknar API:erna för Text Services Framework eftersom appen inte behöver ha detaljerad kunskap om texttjänsterna. På så sätt kan appen ta emot text på valfritt språk och från valfri indatatyp (till exempel tangentbord, tal eller penna).

Viktiga API:er: Windows.UI.Text.Core, CoreTextEditContext

Varför ska du använda api:er för kärntext?

För många appar räcker XAML- eller HTML-textrutekontrollerna för textinmatning och redigering. Men om din app hanterar komplexa textscenarier, till exempel en ordbearbetningsapp, kan du behöva flexibiliteten i en anpassad textredigeringskontroll. Du kan använda CoreWindow-tangentbords-API :er för att skapa textredigeringskontrollen, men de ger inte ett sätt att ta emot kompositionsbaserade textindata, vilket krävs för att stödja östasiatiska språk.

Använd i stället API:erna Windows.UI.Text.Core när du behöver skapa en anpassad textredigeringskontroll. Dessa API:er är utformade för att ge dig stor flexibilitet när det gäller att bearbeta textindata, på valfritt språk, och ge dig den textupplevelse som passar bäst för din app. Textinmatnings- och redigeringskontroller som skapats med kärntext-API:er kan ta emot textindata från alla befintliga textinmatningsmetoder på Windows-enheter, från Text Services Framework-baserade indatametodredigerare (IME) och handskrift på datorer till WordFlow-tangentbordet (som tillhandahåller automatisk korrigering, förutsägelse och diktering) på mobila enheter.

Arkitektur

Följande är en enkel representation av textinmatningssystemet.

  • "Application" representerar en Windows-app som är värd för en anpassad redigeringskontroll som skapats med hjälp av api:er för kärntext.
  • API:er för Windows.UI.Text.Core underlättar kommunikationen med texttjänster via Windows. Kommunikationen mellan textredigeringskontrollen och texttjänsterna hanteras främst via ett CoreTextEditContext-objekt som tillhandahåller metoder och händelser för att underlätta kommunikationen.

Arkitekturdiagram för CoreText

Textintervall och val

Redigeringskontroller ger utrymme för textinmatning och användarna förväntar sig att redigera text var som helst i det här utrymmet. Här förklarar vi det textpositioneringssystem som används av API:erna för kärntext och hur intervall och val representeras i det här systemet.

Applikationsmarkörposition

Textintervall som används med kärntextens API:er uttrycks i form av markörpositioner. En "Application Caret Position (ACP)" är ett nollbaserat tal som anger antalet tecken från början av textströmmen omedelbart före markören, såsom visas här.

Skärmbild som visar Application Caret Position (ACP) och antalet tecken

Textintervall och val

Textintervall och markeringar representeras av CoreTextRange-strukturen som innehåller två fält:

Fält Datatyp Beskrivning
StartCaretPosition Nummer [JavaScript] | System.Int32 [.NET] | int32 [C++] Startpositionen för ett intervall är ACP omedelbart före det första tecknet.
EndCaretPosition Nummer [JavaScript] | System.Int32 [.NET] | int32 [C++] Slutpositionen för ett intervall är ACP:n direkt efter det sista tecknet.

 

I det textintervall som visades tidigare anger till exempel intervallet [0, 5] ordet "Hello". StartCaretPosition måste alltid vara mindre än eller lika med EndCaretPosition. Intervallet [5, 0] är ogiltigt.

Insättningspunkt

Den aktuella caret-positionen, som ofta kallas insättningspunkt, representeras genom att startCaretPosition anges som lika med EndCaretPosition.

Icke sammanhängande markering

Vissa redigeringskontroller stöder icke-sammanhängande val. Till exempel stöder Microsoft Office-appar flera godtyckliga val, och många källkodsredigerare stöder kolumnval. Kärntext-API:erna stöder dock inte icke-sammanhängande val. Redigeringskontroller får bara rapportera en enda sammanhängande markering, oftast det aktiva underintervallet för de icke-sammanhängande valen.

Följande bild visar till exempel en textström med två icke-sammanhängande val: [0, 1] och [6, 11] för vilka redigeringskontrollen endast får rapportera en (antingen [0, 1] eller [6, 11]).

Skärmbild som visar en textmarkering som inte är sammanhängande, där det första tecknet och de fem sista tecknen är markerade.

Arbeta med text

Klassen CoreTextEditContext möjliggör textflöde mellan Windows och redigerar kontroller via händelsen TextUpdating , händelsen TextRequested och metoden NotifyTextChanged .

Redigeringskontrollen tar emot text via TextUppdating-händelser som genereras när användare interagerar med textinmatningsmetoder som tangentbord, tal eller snabbmeddelanden.

När du ändrar text i redigeringskontrollen, till exempel genom att klistra in text i kontrollen, måste du meddela Windows genom att anropa NotifyTextChanged.

Om texttjänsten kräver den nya texten utlöses en TextRequested-händelse . Du måste ange den nya texten i händelsehanteraren TextRequested .

Acceptera textuppdateringar

Redigeringskontrollen bör vanligtvis acceptera begäranden om textuppdatering eftersom de representerar den text som användaren vill ange. I händelsehanteraren TextUpdating förväntas dessa åtgärder av redigeringskontrollen:

  1. Infoga texten som anges i CoreTextTextUpdatingEventArgs.Text i den position som anges i CoreTextTextUpdatingEventArgs.Range.
  2. Placera markeringen på den position som anges i CoreTextTextUpdatingEventArgs.NewSelection.
  3. Meddela systemet att uppdateringen lyckades genom att ange CoreTextTextUpdatingEventArgs.Result till CoreTextTextUpdatingResult.Succeeded.

Det här är till exempel tillståndet för en redigeringskontroll innan användaren skriver "d". Insättningspunkten är [10, 10].

Skärmbild av ett textströmsdiagram som visar insättningspunkten vid [10, 10], före en insättning

När användaren skriver "d" genereras en TextUpdating- händelse med följande data från CoreTextTextUpdatingEventArgs.

I redigeringskontrollen tillämpar du de angivna ändringarna och anger Resultat till Lyckades. Här är tillståndet för kontrollen när ändringarna har tillämpats.

Skärmbild av ett textströmdiagram som visar insättningspunkten vid \[11, 11\], efter en infogning

Avvisa textuppdateringar

Ibland kan du inte tillämpa textuppdateringar eftersom det begärda intervallet finns i ett område i redigeringskontrollen som inte ska ändras. I det här fallet bör du inte tillämpa några ändringar. Meddela i stället systemet att uppdateringen misslyckades genom att ange CoreTextTextUpdatingEventArgs.Result till CoreTextTextUpdatingResult.Failed.

Överväg till exempel en redigeringskontroll som endast accepterar en e-postadress. Blanksteg bör avvisas eftersom e-postadresser inte kan innehålla blanksteg, så när TextUpdating händelser aktiveras för mellanslagstangenten bör du helt enkelt ange Resultat till Misslyckad i din redigeringskontroll.

Meddela textändringar

Ibland gör redigeringskontrollen ändringar i text, till exempel när text klistras in eller korrigeras automatiskt. I dessa fall måste du meddela texttjänsterna om dessa ändringar genom att anropa metoden NotifyTextChanged .

Det här är till exempel tillståndet för en redigeringskontroll innan användaren klistrar in "World". Insättningspunkten är [6, 6].

Skärmbild av ett textströmsdiagram som visar insättningspunkten vid [6, 6], före en infogning

Användaren utför inklistringsåtgärden och redigeringskontrollen när ändringarna har tillämpats:

Skärmbild av ett textströmdiagram som visar insättningspunkten vid \[11, 11\], efter en infogning

När detta händer bör du anropa NotifyTextChanged med följande argument:

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

En eller flera TextRequested-händelser kommer att följa, som du hanterar för att uppdatera texten som texttjänsterna arbetar med.

Prioriterade textuppdateringar

I redigeringskontrollen kanske du vill åsidosätta en textuppdatering för att tillhandahålla funktioner för automatisk korrigering.

Överväg till exempel en redigeringskontroll som tillhandahåller en korrigeringsfunktion som formaliserar sammandragningar. Det här är tillståndet för redigeringskontrollen innan användaren skriver blankstegsnyckeln för att utlösa korrigeringen. Insättningspunkten är [3, 3].

Skärmbild av ett textströmsdiagram som visar insättningspunkten vid [3, 3], före en infogning

Användaren trycker på mellanslagstangenten och en motsvarande TextUpdating händelse aktiveras. Redigeringskontrollen godkänner textuppdateringen. Det här är tillståndet för redigeringskontrollen en kort stund innan korrigeringen har slutförts. Insättningspunkten är [4, 4].

Skärmbild av ett textströmsdiagram som visar insättningspunkten vid [4, 4], efter en infogning

Utanför händelsehanteraren TextUpdating gör redigeringskontrollen följande korrigering. Det här är tillståndet för redigeringskontrollen när korrigeringen är klar. Insättningspunkten är [5, 5].

Skärmbild av ett textströmsdiagram som visar insättningspunkten [5, 5]

När detta händer bör du anropa NotifyTextChanged med följande argument:

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

En eller flera TextRequested-händelser kommer att följa, som du hanterar för att uppdatera texten som texttjänsterna arbetar med.

Tillhandahålla begärd text

Det är viktigt att texttjänsterna har rätt text för att tillhandahålla funktioner som automatisk korrigering eller förutsägelse, särskilt för text som redan fanns i redigeringskontrollen, från att läsa in ett dokument, till exempel, eller text som infogas av redigeringskontrollen enligt beskrivningen i föregående avsnitt. När en TextRequested-händelse aktiveras måste du därför ange texten för närvarande i redigeringskontrollen för det angivna intervallet.

Det kommer att finnas tillfällen då Intervallet i CoreTextTextRequest anger ett intervall som redigeringskontrollen inte kan hantera as-is. Till exempel är Range större än storleken på redigeringskontrollen när händelsen TextRequested inträffar, eller är slutet av Range utanför gränserna. I dessa fall bör du returnera det intervall som är meningsfullt, vilket vanligtvis är en delmängd av det begärda intervallet.

Exempel

Arkivera exempel