Ввод пользовательского текста

Основные текстовые API в пространстве имен Windows.UI.Text.Core позволяют приложению для Windows получать текстовые данные из любой текстовой службы, поддерживаемой на устройствах Windows. API очень похожи на API инфраструктуры текстовых служб в этом приложении в том, что приложению не требуются подробные данные текстовых служб. Это позволяет приложению получать текст на любом языке и из любого типа ввода, например клавиатуры, речи или пера.

Важные API-интерфейсы: Windows.UI.Text.Core, CoreTextEditContext

Зачем использовать API основного текста?

Для многих приложений элементов управления XAML или HTML достаточно для текстового ввода и редактирования. Однако, если ваше приложение обрабатывает сложные сценарии текста, например предназначено для обработки текстов, возможно, потребуется гибкость пользовательского элемента управления редактированием текста. Вы можете использовать API клавиатуры CoreWindow для создания элемента управления редактированием текста, но они не предоставляют способ получить ввод текста на основе композиции, необходимый для поддержки восточноазиатских языков.

Вместо этого используйте API Windows.UI.Text.Core, когда вам нужно создать пользовательский элемент управления редактированием текста. Эти API предназначены для предоставления вам достаточной гибкости в обработке ввода текста на любом языке и обеспечивают удобство работы с текстом соответственно вашему приложению. Ввод текста и элементы управления редактированием, созданные с помощью основных API текста, могут получать ввод текста от всех существующих методов ввода текста на устройствах с Windows: от редакторов метода ввода (IME) на основе инфраструктуры текстовых служб и рукописного ввода на компьютерах до клавиатуры WordFlow (которая предоставляет автозамену, прогнозирование и диктовки) на мобильных устройствах.

Архитектура

Ниже приведено простое представление системы ввода текста.

  • "Приложение" представляет приложение Для Windows, в котором размещается пользовательский элемент управления редактированием, созданный с помощью интерфейсов API основного текста.
  • API Windows.UI.Text.Core упрощают связь с текстовыми службами с помощью Windows. Связь между элементом управления редактированием текста и текстовыми службами обрабатывается главным образом объектом CoreTextEditContext, который предоставляет методы и события для облегчения связи.

Схема архитектуры CoreText

Диапазоны текста и выделение

Элементы управления редактированием предоставляют место для ввода текста, и пользователи могут редактировать текст в любом месте в этом пространстве. Здесь мы описываем систему позиционирования текста, используемую API основного текста, а также диапазоны и выделения, представленные в этой системе.

Положение курсора приложения

Диапазоны текста, используемые с API основного текста, выражаются положениями курсора. "Положение курсора приложения (ACP)" — это число на основе нуля, указывающее количество символов от начала потока текста непосредственно перед курсором, как показано здесь.

Снимок экрана: количество символов позиции курсора приложения (ACP)

Диапазоны текста и выделение

Диапазоны и выделения текста представлены структурой 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]).

Снимок экрана: несмежный выделенный текст, где выделены первый и последние пять символов.

Работа с текстом

Класс CoreTextEditContext обеспечивает поток текста между Windows и элементами управления редактированием с помощью события TextUpdating, события TextRequested и метода NotifyTextChanged.

Элемент управления редактированием получает текст с помощью событий TextUpdating, которые создаются, когда пользователи взаимодействуют с методами ввода текста с клавиатуры, речевым вводом или IME.

При изменении текста в вашем элементе управления редактированием, например путем вставки текста в элемент управления, необходимо уведомить Windows, вызвав NotifyTextChanged.

Если текстовая служба запрашивает новый текст, вызывается событие TextRequested. Необходимо предоставить новый текст в обработчике событий TextRequested.

Принятие обновлений текста

Элемент управления редактированием обычно должен принимать запросы на обновление текста, так как они представляют собой текст, который хочет ввести пользователь. В обработчике событий TextUpdating эти действия ожидаются от элемента управления редактированием:

  1. Вставьте текст, определенный в CoreTextTextUpdatingEventArgs.Text, в положение, указанное в CoreTextTextUpdatingEventArgs.Range.
  2. Установите выделение в положении, указанном в CoreTextTextUpdatingEventArgs.NewSelection.
  3. Уведомите систему об успешном обновлении, установив для параметра CoreTextTextUpdatingEventArgs.Result значение CoreTextTextUpdatingResult.Succeeded.

Например, это состояние элемента управления редактированием до того, как пользователь ввел "d". Точка вставки находится в [10, 10].

Снимок экрана: схема потока текста, показывающая точку вставки в [10, 10], перед вставкой

Когда пользователь вводит "d", возникает событие TextUpdating со следующими данными CoreTextTextUpdatingEventArgs :

В вашем элементе управления редактированием примените указанные изменения и установите для параметра Result значение Succeeded. Далее описано состояние элемента управления после применения изменений.

Снимок экрана: схема потока текста, показывающая точку вставки в \[11, 11\], после вставки

Отклонение обновлений текста

Иногда вы не можете применить обновления текста, так как запрошенный диапазон находится в области элемента управления редактированием, которую не следует изменять. В этом случае вам не нужно применять изменения. Вместо этого уведомите систему о невозможности обновления, установив для параметра CoreTextTextUpdatingEventArgs.Result значение CoreTextTextUpdatingResult.Failed.

Например, рассмотрим элемент управления редактированием, который принимает только адрес электронной почты. Пробелы должны быть отклонены, так как адреса электронной почты не могут содержать пробелов. Поэтому, когда вызываются события TextUpdating для клавиши ПРОБЕЛ, необходимо просто установить для параметра Result значение Failed в элементе управления редактированием.

Уведомление об изменениях текста

Иногда элемент управления редактированием вносит изменения в текст, например при вставке текста или автоматических исправлениях. В таких случаях вы должны уведомить текстовые службы об этих изменениях, вызвав метод NotifyTextChanged.

Например, это состояние элемента управления редактированием до вставки пользователем слова World. Точка вставки находится в [6, 6].

Снимок экрана: схема потока текста, показывающая точку вставки в [6, 6], перед вставкой

Пользователь выполняет действие вставки и элемент управления "Изменить" после применения изменений:

Снимок экрана: схема потока текста, показывающая точку вставки в \[11, 11\], после вставки

В этом случае следует вызвать NotifyTextChanged со следующими аргументами:

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

Последует одно или несколько событий TextRequested, которые вы обрабатываете для обновления текста, находящегося в ведении текстовых служб.

Переопределение обновлений текста

В вашем элементе управления редактированием, возможно, вам придется переопределить обновление текста для предоставления функций автозамены.

Например, рассмотрим элемент управления редактированием, который предоставляет функцию исправления, оформляющую сужения. Это состояние элемента управления редактированием до того, как пользователь нажал клавишу ПРОБЕЛ для активации исправления. Точка вставки находится в [3, 3].

Снимок экрана: схема потока текста, на которой показана точка вставки [3, 3], перед вставкой

Пользователь нажимает клавишу ПРОБЕЛ, и вызывается соответствующее событие TextUpdating . Элемент управления редактированием принимает обновление текста. Это состояние элемента управления редактированием в течение короткого момента перед завершением исправления. Точка вставки находится в [4, 4].

Снимок экрана: схема потока текста, показывающая точку вставки [4, 4], после вставки

За пределами обработчика событий TextUpdating элемент управления редактированием вносит следующее исправление. Это состояние элемента управления редактированием после завершения исправления. Точка вставки находится в [5, 5].

Снимок экрана: схема потока текста, показывающая точку вставки в [5, 5]

В этом случае следует вызвать NotifyTextChanged со следующими аргументами:

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

Последует одно или несколько событий TextRequested, которые вы обрабатываете для обновления текста, находящегося в ведении текстовых служб.

Предоставление запрашиваемого текста

Важно, чтобы текстовые службы имели правильный текст для предоставления таких функций, как автозамена или прогнозирование, особенно для текста, который уже существовал в элементе управления редактированием, например с загрузки документа, или текста, который вставлен элементом управления редактированием, как описано в предыдущих разделах. Поэтому, когда возникает событие TextRequested, необходимо предоставить текст, который в настоящее время находится в вашем элементе управления редактированием для определенного диапазона.

Иногда Range в CoreTextTextRequest определяет диапазон, который ваш элемент управления редактированием не может вставить "как есть". Например, Range больше, чем размер элемента управления редактированием в момент события TextRequested, или конец Range выходит за рамки. В таких случаях вы должны вернуть любой разумный диапазон. Обычно это подмножество запрашиваемого диапазона.

Примеры

Примеры архива