Freigeben über


Das Threadmodell für Freihandeingaben

Einer der Vorteile von Freihandeingaben auf einem Tablet ist, dass sie sich ähnlich anfühlen wie das Schreiben mit einem normalen Stift auf Papier. Um dies zu erreichen, erfasst der Tabletstift Eingabedaten mit einer viel höherer Rate als eine Maus und rendert die Freihandeingabe, während der Benutzer schreibt. Der Benutzeroberflächenthread der Anwendung reicht nicht aus, um Stiftdaten und Freihandeingaben zu erfassen, weil er blockiert werden kann. Um dies zu lösen, verwendet eine WPF-Anwendung zwei zusätzliche Threads, wenn ein Benutzer Freihandeingaben vornimmt.

In der folgenden Liste werden die Threads beschrieben, die zum Erfassen und Rendern digitaler Freihandeingaben beitragen:

  • Stiftthread: Der Thread, der Eingaben aus dem Eingabestift übernimmt. (In Wirklichkeit ist dies ein Threadpool, aber dieses Thema bezieht sich auf ihn als Stiftthread.)

  • Anwendungsbenutzeroberflächen-Thread: Der Thread, der die Benutzeroberfläche der Anwendung steuert.

  • Dynamischer Renderingthread: Der Thread, der die Freihandeingabe rendert, während der Benutzer zeichnet. Der dynamische Renderingthread unterscheidet sich vom Thread, der andere Benutzeroberflächenelemente für die Anwendung rendert, wie im Threadingmodell von Windows Presentation Foundation beschrieben.

Das Freihandeingabemodell ist das gleiche, unabhängig davon, ob die Anwendung InkCanvas oder ein benutzerdefiniertes Steuerelement ähnlich dem in Erstellen eines Freihandeingabe-Steuerelements beschriebenen verwendet. Obwohl in diesem Thema Threading in Bezug auf InkCanvas behandelt wird, gelten die gleichen Konzepte, wenn Sie ein benutzerdefiniertes Steuerelement erstellen.

Übersicht über Threading

Die folgende Abbildung veranschaulicht das Threadingmodell, wenn ein Benutzer eine Freihandeingabe vornimmt:

Threading model while drawing a stroke.

  1. Aktionen, die auftreten, während der Benutzer zeichnet

    1. Wenn der Benutzer einen Strich zeichnet, gehen die Stiftpunkte im Stiftthread ein. Eingabestift-Plug-Ins (einschließlich DynamicRenderer) akzeptieren die Eingabestiftpunkte im Stiftthread und haben die Möglichkeit, sie zu ändern, bevor InkCanvas sie empfängt.

    2. DynamicRenderer rendert die Eingabestiftpunkte im dynamischen Renderingthread. Dies geschieht gleichzeitig mit dem vorherigen Schritt.

    3. InkCanvas empfängt die Eingabestiftpunkte im Benutzeroberflächenthread.

  2. Aktionen, die auftreten, nachdem der Benutzer das Zeichnen beendet hat

    1. Wenn der Benutzer das Zeichnen beendet hat, erstellt InkCanvas ein Stroke-Objekt und fügt es dem InkPresenter hinzu, der es statisch rendert.

    2. Der Benutzeroberflächenthread benachrichtigt DynamicRenderer, dass der Strich statisch gerendert wird, sodass DynamicRenderer die visuelle Darstellung des Strichs entfernt.

Freihandsammlung und Eingabestift-Plug-Ins

Jedes UIElement verfügt über eine StylusPlugInCollection. Die StylusPlugIn-Objekte in StylusPlugInCollection empfangen die Stiftpunkte im Stiftthread und können diese ändern. Die StylusPlugIn-Objekte erhalten die Eingabestiftpunkte entsprechend ihrer Reihenfolge in StylusPlugInCollection.

Die folgende Abbildung veranschaulicht die hypothetische Situation, dass die StylusPlugIns-Sammlung eines UIElementstylusPlugin1, einen DynamicRenderer und stylusPlugin2 (in dieser Reihenfolge) enthält.

Order of Stylus Plugins affect output.

In der Abbildung oben ist das folgende Verhalten zu beobachten:

  1. StylusPlugin1 ändert die Werte für x und y.

  2. DynamicRenderer empfängt die geänderten Eingabestiftpunkte und rendert sie im dynamischen Renderingthread.

  3. StylusPlugin2 empfängt die geänderten Eingabestiftpunkte und ändert die Werte für x und y weiter.

  4. Die Anwendung erfasst die Eingabestiftpunkte, und wenn der Benutzer den Strich beendet hat, rendert sie den Strich statisch.

Angenommen, stylusPlugin1 beschränkt die Eingabestiftpunkte auf ein Rechteck, und stylusPlugin2 übersetzt die Eingabestiftpunkte nach rechts. Im vorherigen Szenario empfängt DynamicRenderer eingeschränkte Eingabestiftpunkte, aber nicht die übersetzten Eingabestiftpunkte. Wenn der Benutzer den Strich zeichnet, wird der Strich innerhalb der Grenzen des Rechtecks gerendert, der Strich wird jedoch erst übersetzt, wenn der Benutzer den Stift absetzt.

Ausführen von Vorgängen mit einem Eingabestift-Plug-In im Benutzeroberflächenthread

Da genaue Treffertests nicht im Stiftthread ausgeführt werden können, erhalten einige Elemente gelegentlich Stifteingaben, die für andere Elemente vorgesehen sind. Wenn Sie sicherstellen müssen, dass die Eingabe ordnungsgemäß weitergeleitet wurde, bevor Sie einen Vorgang ausführen, abonnieren Sie den Vorgang in der OnStylusDownProcessed-, OnStylusMoveProcessed- oder OnStylusUpProcessed-Methode, und führen Sie ihn dort aus. Diese Methoden werden vom Anwendungsthread aufgerufen, nachdem genaue Treffertests durchgeführt wurden. Um diese Methoden zu abonnieren, rufen Sie die NotifyWhenProcessed-Methode in der Methode auf, die im Stiftthread auftritt.

Die folgende Abbildung veranschaulicht die Beziehung zwischen dem Stiftthread und dem Benutzeroberflächenthread in Bezug auf die Stiftereignisse eines StylusPlugIn.

Ink Threading Models (UI and Pen)

Rendern von Freihandeingaben

Während der Benutzer eine Eingabe vornimmt, rendert DynamicRenderer die Freihandeingabe in einem separaten Thread, sodass die Freihandeingabe auch dann aus dem Stift „fließt“, wenn Benutzeroberflächenthread ausgelastet ist. DynamicRenderer erstellt eine visuelle Struktur im dynamischen Renderingthread, während die Eingabestiftpunkte erfasst werden. Wenn der Benutzer die Freihandeingabe beendet hat, möchte DynamicRenderer benachrichtigt werden, wenn die Anwendung den nächsten Renderingdurchlauf ausführt. Nachdem die Anwendung den nächsten Renderingdurchlauf abgeschlossen hat, bereinigt DynamicRenderer seine visuelle Struktur. Dieser Prozess wird anhand des folgenden Diagramms veranschaulicht.

Ink threading diagram

  1. Der Benutzer beginnt mit der Freihandeingabe.

    1. DynamicRenderer erstellt die visuelle Struktur.
  2. Der Benutzer führt die Freihandeingabe aus.

    1. DynamicRenderer erstellt die visuelle Struktur.
  3. Der Benutzer beendet die Freihandeingabe.

    1. InkPresenter fügt den Strich der visuellen Struktur hinzu.

    2. Die MIL (Media Integration Layer) rendert die Striche statisch.

    3. DynamicRenderer bereinigt die visuellen Elemente.