Share via


自訂文字輸入

Windows.UI.Text.Core 命名空間中的核心文字 API 可讓 Windows 應用程式從 Windows 裝置上支援的任何文字服務接收文字輸入。 API 類似於 文字服務架構 API,應用程式不需要具備文字服務的詳細知識。 這可讓應用程式以任何語言和輸入類型接收文字,例如鍵盤、語音或手寫筆。

重要 API:Windows.UI.Text.Core、CoreTextEditContext

為什麼要使用核心文字 API?

對於許多應用程式,XAML 或 HTML 文字框控制項就足以用於文字輸入和編輯。 不過,如果您的應用程式處理複雜的文字案例,例如文字處理應用程式,您可能需要自訂文字編輯控制項的彈性。 您可以使用 CoreWindow 鍵盤 API 來建立文字編輯控制項,但這些不會提供接收以組合為基礎的文字輸入的方式,這是支援東亞語言的必要專案。

當您需要建立自訂文字編輯控制項時,請改用 Windows.UI.Text.Core API。 這些 API 的設計目的是讓您以任何語言處理文字輸入,並提供最適合您應用程式的文字體驗。 使用核心文字 API 建置的文字輸入和編輯控制項,可以從 Windows 裝置上所有現有的文字輸入法、從 以文字服務架構 為基礎的輸入法編輯器(IME)以及電腦上的手寫,到行動裝置上的 WordFlow 鍵盤(提供自動更正、預測和聽寫)。

架構

以下是文字輸入系統的簡單表示法。

  • 「應用程式」代表裝載使用核心文字 API 所建置之自訂編輯控制項的 Windows 應用程式。
  • Windows.UI.Text.Core API 可協助透過 Windows 與文字服務進行通訊。 文字編輯控制項與文字服務之間的通訊主要是透過 CoreTextEditContext 物件來處理,該物件會提供方法來促進通訊。

CoreText architecture diagram

文字範圍和選取範圍

編輯控制項提供文字項目的空間,而使用者預期在此空間中的任何位置編輯文字。 在這裡,我們會說明核心文字 API 所使用的文字定位系統,以及如何在此系統中呈現範圍和選取範圍。

應用程式插入號位置

與核心文字 API 搭配使用的文字範圍會以插入號位置表示。 「應用程式插入號位置(ACP)」是以零起始的數位,表示插入號前文字串流開頭的字元計數,如下所示。

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

文字範圍和選取範圍

文字範圍和選取範圍是由 CoreTextRange 結構來表示,其中包含兩個欄位:

欄位 資料類型 描述
StartCaretPosition 數位 [JavaScript] | System.Int32 [.NET] | int32 [C++] 範圍的開始位置是 ACP,緊接在第一個字元之前。
EndCaretPosition 數位 [JavaScript] | System.Int32 [.NET] | int32 [C++] 範圍的結尾位置是緊接在最後一個字元之後的 ACP。

 

例如,在先前顯示的文字範圍中,範圍 [0, 5] 會指定 「Hello」 這個字。 StartCaretPosition 必須一律小於或等於 EndCaretPosition。 範圍 [5, 0] 是有效的。

插入點

目前插入號位置,通常稱為插入點,是藉由將 StartCaretPosition 設定為等於 EndCaretPosition 來表示。

非連續選取

某些編輯控制項支援不連續的選取專案。 例如,Microsoft Office 應用程式 支援多個任意選取專案,而且許多原始程式碼編輯器都支援資料行選取。 不過,核心文字 API 不支援非連續選取專案。 編輯控制項只能報告單一連續選取範圍,通常是非連續選取範圍的使用中子範圍。

例如,下圖顯示具有兩個非連續選取範圍的文字串流:[0、1] 和 [6, 11],編輯控制項必須只報告一個 ([0, 1] 或 [6, 11])。

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

使用文字

CoreTextEditContext 類別可讓 Windows 之間的文字流動,並透過 TextUpdating 事件、TextRequested 事件和 NotifyTextChanged 方法編輯控制項。

您的編輯控制項會透過 TextUpdating 事件接收文字,當使用者與鍵盤、語音或 IME 等文字輸入法互動時所產生的事件。

例如,當您變更編輯控制項中的文字時,將文字貼入控制項時,您必須呼叫 NotifyTextChanged 來通知 Windows。

如果文字服務需要新的文字,則會 引發 TextRequested 事件。 您必須在 TextRequested 事件處理常式中提供新的文字。

接受文字更新

您的編輯控制項通常應該接受文字更新要求,因為它們代表使用者想要輸入的文字。 在 TextUpdating 事件處理常式中,編輯控制項預期會有這些動作:

  1. 將 CoreTextTextUpdatingEventArgs.Text 中指定的文字插入 CoreTextTextUpdatingEventArgs.Range 中指定的位置。
  2. 將選取範圍放在 CoreTextTextUpdatingEventArgs.NewSelection 中指定的位置。
  3. 將 CoreTextTextUpdatingEventArgs.Result 設定為 CoreTextTextUpdatingResult.Succeeded,通知系統更新成功。

例如,這是使用者輸入 「d」 之前編輯控制項的狀態。 插入點位於 [10, 10]。

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

當使用者輸入 「d」時,會以下列 CoreTextTextUpdatingEventArgs 資料引發 TextUpdating 事件:

在編輯控制項中,套用指定的變更,並將 [結果] 設定[成功]。 以下是套用變更之後控制項的狀態。

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

拒絕文字更新

有時候,您無法套用文字更新,因為要求的範圍位於不應該變更的編輯控制項區域中。 在此情況下,您不應該套用任何變更。 相反地,請將 CoreTextTextUpdatingEventArgs.Result 設定為 CoreTextTextUpdatingResult.Failed,通知系統更新失敗。

例如,請考慮只接受電子郵件地址的編輯控制項。 因為電子郵件位址不能包含空格,所以當空格鍵引發 TextUpdating 事件時,您應該只將 [結果] 設定為 [編輯] 控制項中的 [失敗]。

通知文字變更

有時候,您的編輯控制項會變更文字,例如文字貼上或自動更正時。 在這些情況下,您必須呼叫 NotifyTextChanged 方法來通知文字服務這些變更。

例如,這是使用者貼上 「World」 之前編輯控制項的狀態。 插入點位於 [6, 6]。

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

使用者會在套用變更之後執行貼上動作和編輯控制項:

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

發生這種情況時,您應該使用下列自變數呼叫 NotifyTextChanged:

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

將會追蹤一或多個 TextRequested 事件,您可以處理這些事件來更新文字服務正在使用的文字。

覆寫文字更新

在編輯控制項中,您可能會想要覆寫文字更新以提供自動更正功能。

例如,請考慮提供正規化收縮的更正功能的編輯控制項。 這是使用者輸入空格鍵以觸發更正之前編輯控制項的狀態。 插入點位於 [3, 3]。

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

使用者按下空格鍵,並引發對應的 TextUpdating 事件。 編輯控制項接受文字更新。 這是編輯控制項的狀態,在更正完成前的短暫時間。 插入點位於 [4, 4]。

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

在 TextUpdating 事件處理常式之外,編輯控制項會進行下列更正。 這是完成更正之後編輯控制項的狀態。 插入點位於 [5, 5]。

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

發生這種情況時,您應該使用下列自變數呼叫 NotifyTextChanged:

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

將會追蹤一或多個 TextRequested 事件,您可以處理這些事件來更新文字服務正在使用的文字。

提供要求的文字

文字服務必須有正確的文字來提供自動更正或預測等功能,特別是對於已經存在於編輯控制項中的文字,例如載入檔,或編輯控制項所插入的文字,如前幾節所述。 因此,每當 引發 TextRequested 事件時,您必須為指定的範圍提供目前編輯控制項中的文字。

CoreTextTextRequest 中的 Range 會指定編輯控制項無法依目前的方式容納的範圍。 例如,Range 大於 TextRequested 事件時編輯控制項的大小,或 Range 的結尾超出界限。 在這些情況下,您應該傳回任何有意義的範圍,這通常是所要求範圍的子集。

範例

封存範例