Поделиться через


Потоковая модель рукописного ввода

Одним из преимуществ рукописного ввода на планшетном ПК является то, что оно очень похоже на письмо с обычным пером и бумагой. Для этого перо планшета собирает входные данные с гораздо более высокой скоростью, чем мышь, и отрисовывает рукописный ввод по мере записи пользователем. Потока пользовательского интерфейса приложения недостаточно для сбора данных пера и отрисовки рукописного ввода, так как он может оказаться заблокированным. Чтобы решить эту проблему, приложение WPF использует два дополнительных потока при осуществлении рукописного ввода пользователем.

В следующем списке описываются потоки, участвующие в сборе и отрисовке цифрового рукописного ввода.

  • Поток пера — поток, который принимает входные данные от пера. (На самом деле это пул потоков, но этот раздел относится к нему как к потоку пера.)

  • Поток пользовательского интерфейса приложения — поток, который управляет пользовательским интерфейсом приложения.

  • Динамический поток отрисовки — поток, который отрисовывает рукописный ввод, пока пользователь рисует росчерк. Динамический поток отрисовки отличается от потока, который отображает другие элементы пользовательского интерфейса для приложения, как упоминалось в разделе Модель потоков Window Presentation Foundation.

Модель рукописного ввода одинакова вне зависимости от того, использует ли приложение InkCanvas или пользовательский элемент управления, подобный элементу управления, используемому в разделе справки Создание элемента управления для рукописного ввода. Хотя в этом разделе рассматриваются потоки с точки зрения InkCanvas, при создании пользовательского элемента управления применяются те же концепции.

Общие сведения о работе с потоками

На следующей схеме показана модель потоков при отрисовке пользователем росчерка.

Threading model while drawing a stroke.

  1. Действия, выполняемые при рисовании росчерка пользователем

    1. Когда пользователь рисует росчерк, точки пера поступают в поток пера. Подключаемые модули пера, в том числе DynamicRenderer, принимают точки пера в потоке пера и имеют возможность изменять их до их получения InkCanvas.

    2. DynamicRenderer отрисовывает точки пера в динамическом потоке отрисовки. Это происходит одновременно с предыдущим шагом.

    3. InkCanvas принимает точки пера в потоке пользовательского интерфейса.

  2. Действия, происходящие после завершения росчерка пользователем

    1. Когда пользователь завершает рисование росчерка, InkCanvas он создает объект Stroke и добавляет его в экземпляр InkPresenter, который статически отрисовывает его.

    2. Поток пользовательского интерфейса оповещает DynamicRenderer о том, что росчерк статически визуализируется и DynamicRenderer удаляет визуальное представление росчерка.

Сбор рукописного ввода и подключаемые модули пера

Каждый UIElement имеет коллекцию StylusPlugInCollection. Объекты StylusPlugIn в StylusPlugInCollection участвуют в приеме и изменении точек пера в потоке пера. Объекты StylusPlugIn получают точки пера в соответствии с их порядком в StylusPlugInCollection.

На следующей схеме показана гипотетическая ситуация, в которой коллекция StylusPlugIns объектов UIElement содержит stylusPlugin1, DynamicRenderer и stylusPlugin2, в этом порядке.

Order of Stylus Plugins affect output.

На предыдущей схеме происходит следующее поведение.

  1. StylusPlugin1 изменяет значения x и y.

  2. DynamicRenderer получает измененные точки пера и отрисовывает их в динамическом потоке отрисовки.

  3. StylusPlugin2 получает измененные точки пера и дополнительно изменяет значения x и y.

  4. Приложение собирает точки пера и, когда пользователь завершает росчерк, статически отрисовывает его.

Предположим, что stylusPlugin1 ограничивает точки пера в пределах прямоугольника, а stylusPlugin2 транслирует их в поток справа. В предыдущем сценарии DynamicRenderer получает ограниченные точки пера, но не преобразованные точки пера. Когда пользователь рисует росчерк, последний отображается в границах прямоугольника, но не преобразуется до тех пор, пока пользователь не поднимет перо.

Выполнение операций с подключаемым модулем пера в потоке пользовательского интерфейса

Поскольку точное тестирование попадания невозможно выполнить в потоке пера, элементы могут время от времени получать входные данные пера, предназначенные для других элементов. Если необходимо убедиться, что входные данные были перенаправлены правильно перед выполнением операции, подпишитесь и выполните операцию в методе или OnStylusDownProcessed, OnStylusMoveProcessed или OnStylusUpProcessed. Эти методы вызываются потоком приложения после выполнения точного тестирования попадания. Чтобы подписаться на эти методы, вызовите метод NotifyWhenProcessed в методе, который используется потоком пера.

На следующей схеме показана связь между потоком пера и потоком пользовательского интерфейса относительно событий пера StylusPlugIn.

Ink Threading Models (UI and Pen)

Отрисовка рукописных данных

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

Ink threading diagram

  1. Пользователь начинает росчерк.

    1. DynamicRenderer создает визуальное дерево.
  2. Пользователь продолжает росчерк.

    1. DynamicRenderer собирает визуальное дерево.
  3. Пользователь завершает росчерк.

    1. InkPresenter добавляет росчерк к визуальному дереву.

    2. Уровень интеграции мультимедиа (MIL) статически отрисовывает росчерки.

    3. DynamicRenderer выполняет очистку визуальных элементов.