Freigeben über


Das Threadingmodell für Freihandeschrift

Einer der Vorteile von Tinte auf einem Tablet-PC ist, dass es sich sehr ähnlich wie das Schreiben mit einem normalen Stift auf Papier anfühlt. Um dies zu erreichen, erfasst der Tabletstift Eingabedaten mit einer viel höherer Rate als eine Maus und rendert die Freihandschrift noch während des Schreibens. 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 während der Eingabe von Freihandschrift.

In der folgenden Liste werden die Threads beschrieben, die am Sammeln und Rendern von digitaler Tinte teilnehmen.

  • Stiftthread: Der Thread, der die Eingabe des Tablettstifts annimmt. (In Wirklichkeit handelt es sich hierbei um einen Threadpool. In diesem Artikel wird er jedoch „Stiftthread“ genannt.)

  • Anwendungsbenutzeroberflächenthread – der Thread, der die Benutzeroberfläche der Anwendung steuert.

  • Dynamischer Renderingthread: Der Thread, der die Freihandschrift während des Zeichnens rendert. Der dynamische Renderingthread unterscheidet sich vom Thread, der andere UI-Elemente für die Anwendung rendert, wie in Window Presentation Foundation Threading Modelerwähnt.

Das Freihandschriftmodell bleibt gleich, 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 Strich gezeichnet wird:

Threadingmodell beim Zeichnen eines Strichs.

  1. Aktionen, die während des Zeichnens auftreten

    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 Tablettstiftpunkte im dynamischen Renderingthread. Dies geschieht gleichzeitig mit dem vorherigen Schritt.

    3. InkCanvas empfängt die Tablettstiftpunkte im UI-Thread.

  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 UIElement-Elements stylusPlugin1, ein DynamicRenderer-Element und stylusPlugin2 (in dieser Reihenfolge) enthält.

Die Reihenfolge der Tablettstift-Plug-Ins wirkt sich auf die Ausgabe aus.

Im vorherigen Diagramm erfolgt das folgende Verhalten:

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

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

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

  4. Die Anwendung erfasst die Tablettstiftpunkte, und wenn die manuelle Stricheingabe beendet wird, 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 UI-Thread in Bezug auf die Tablettstiftereignisse eines StylusPlugIn-Elements.

Threadingmodelle für Freihandschrift (UI und Stift)

Rendern von Freihandschrift

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 die nächste Renderingübergabe abgeschlossen hat, bereinigt DynamicRenderer seine visuelle Struktur. Das folgende Diagramm veranschaulicht diesen Prozess.

Diagramm zu Freihandthreading

  1. Die manuelle Eingabe eines Strichs beginnt.

    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.