Beispiel für die RealTimeStylus-Freihandsammlung
Diese Anwendung veranschaulicht die Freihandsammlung und das Rendering bei Verwendung der RealTimeStylus-Klasse .
Das InkCollection-Projekt
Dieses Beispiel besteht aus einer einzelnen Projektmappe, die ein Projekt enthält, InkCollection. Die Anwendung definiert den Namespace, der InkCollection
eine einzelne Klasse enthält, die auch als bezeichnet wird InkCollection
. Die -Klasse erbt von der Form-Klasse und implementiert die IStylusAsyncPlugin-Schnittstelle .
namespace InkCollection
{
public class InkCollection : Form, IStylusAsyncPlugin
{
//...
Die InkCollection-Klasse definiert eine Reihe von privaten Konstanten, die zum Angeben verschiedener Freihandstärken verwendet werden. Die -Klasse deklariert auch private Instanzen der RealTimeStylus-Klasse , myRealTimeStylus
der DynamicRenderer-Klasse , myDynamicRenderer
und der Renderer-KlassemyRenderer
. Der DynamicRenderer rendert den Strich , der gerade erfasst wird. Das Renderer-Objekt , myRenderer
rendert Stroke-Objekte, die bereits gesammelt wurden.
private const float ThinInkWidth = 10;
private const float MediumInkWidth = 100;
private const float ThickInkWidth = 200;
private RealTimeStylus myRealTimeStylus;
private DynamicRenderer myDynamicRenderer;
private Renderer myRenderer;
Die -Klasse deklariert auch ein Hashtable-Objekt , myPackets
das zum Speichern von Paketdaten verwendet wird, die von einem oder mehreren Cursor-Objekten gesammelt werden. Die ID-Werte des Stylus-Objekts werden als Hashtabellenschlüssel verwendet, um die für ein bestimmtes Cursor-Objekt gesammelten Paketdaten eindeutig zu identifizieren.
Eine private instance des Ink-Objekts speichert stroke-Objekte, myInk
die von gesammelt wurdenmyRealTimeStylus
.
private Hashtable myPackets;
private Ink myInk;
Das Formularladeereignis
Im Load-Ereignishandler für das Formular wird mithilfe des DynamicRenderer instanziiert, myDynamicRenderer
der ein Steuerelement als Argument akzeptiert und myRenderer
mit einem Konstruktor ohne Argument erstellt wird.
private void InkCollection_Load(object sender, System.EventArgs e)
{
myDynamicRenderer = new DynamicRenderer(this);
myRenderer = new Renderer();
// ...
Achten Sie auf den Kommentar, der auf die Instanziierung der Renderer folgt, da myDynamicRenderer
beim Rendern der Freihandeingabe die Standardwerte für DrawingAttributes verwendet werden. Dies ist ein Standardverhalten. Wenn Sie jedoch die Freihandeingabe, die von einem anderen Aussehen gerendert wird myDynamicRenderer
, als die von myRenderer
gerenderte Freihandeingabe verwenden möchten, können Sie die DrawingAttributes-Eigenschaft für myDynamicRenderer
ändern. Heben Sie dazu die Auskommentierung der folgenden Zeilen auf, bevor Sie die Anwendung erstellen und ausführen.
// myDynamicRenderer.DrawingAttributes.PenTip = PenTip.Rectangle;
// myDynamicRenderer.DrawingAttributes.Height = (.5F)*MediumInkWidth;
// myDynamicRenderer.DrawingAttributes.Transparency = 128;
Als Nächstes erstellt die Anwendung das RealTimeStylus-Objekt , das zum Empfangen von Eingabestiftbenachrichtigungen verwendet wird, und fügt das DynamicRenderer-Objekt der synchronen Plug-In-Benachrichtigungswarteschlange hinzu.
myRealTimeStylus
Fügt insbesondere der SyncPluginCollection-Eigenschaft hinzumyDynamicRenderer
.
myRealTimeStylus = new RealTimeStylus(this, true);
myRealTimeStylus.SyncPluginCollection.Add(myDynamicRenderer);
Das Formular wird dann der asynchronen Plug-In-Benachrichtigungswarteschlange hinzugefügt.
InkCollection
Insbesondere wird der AsyncPluginCollection-Eigenschaft hinzugefügt.
myRealTimeStylus
Schließlich werden und myDynamicRenderer
aktiviert, und myPackets und myInk werden instanziiert.
myRealTimeStylus.AsyncPluginCollection.Add(this);
myRealTimeStylus.Enabled = true;
myDynamicRenderer.Enabled = true;
myPackets = new Hashtable();
myInk = new Ink();
}
Neben dem Einbinden der Menühandler zum Ändern der Freihandfarbe und -größe ist vor der Implementierung der Schnittstelle ein weiterer kurzer Codeblock erforderlich. Das Beispiel muss das Paint-Ereignis des Formulars behandeln. Im Ereignishandler muss die Anwendung aktualisiert myDynamicRenderer
werden, da es möglich ist, dass zum Zeitpunkt des Paint-Ereignisses ein Stroke-Objekt erfasst wird. In diesem Fall muss der Teil des Stroke-Objekts, der bereits gesammelt wurde, neu gezeichnet werden. Der statische Renderer wird verwendet, um Stroke-Objekte, die bereits erfasst wurden, neu zu zeichnen. Diese Striche befinden sich im Ink-Objekt , da sie dort platziert werden, wenn sie gezeichnet werden, wie im nächsten Abschnitt gezeigt.
private void InkCollection_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
myDynamicRenderer.Refresh();
myRenderer.Draw(e.Graphics, myInk.Strokes);
}
Implementieren der IStylusAsyncPlugin-Schnittstelle
Die Beispielanwendung definiert die Typen von Benachrichtigungen, die sie in der Implementierung der DataInterest-Eigenschaft erhalten möchten. Die DataInterest-Eigenschaft definiert daher, welche Benachrichtigungen das RealTimeStylus-Objekt an das Formular weiterleitet. Für dieses Beispiel definiert die DataInterest-Eigenschaft das Interesse an den Benachrichtigungen StylusDown, Packets, StylusUp und Error über die DataInterestMask-Enumeration .
public DataInterestMask DataInterest
{
get
{
return DataInterestMask.StylusDown |
DataInterestMask.Packets |
DataInterestMask.StylusUp |
DataInterestMask.Error;
}
}
Die StylusDown-Benachrichtigung wird angezeigt, wenn der Stift die Digitalisiereroberfläche berührt. In diesem Fall ordnet das Beispiel ein Array zu, das zum Speichern der Paketdaten für das Stylus-Objekt verwendet wird. Die StylusDownData aus der StylusDown-Methode wird dem Array hinzugefügt, und das Array wird mithilfe der Id-Eigenschaft des Stylus-Objekts als Schlüssel in die Hashtabelle eingefügt.
public void StylusDown(RealTimeStylus sender, StylusDownData data)
{
ArrayList collectedPackets = new ArrayList();
collectedPackets.AddRange(data.GetData());
myPackets.Add(data.Stylus.Id, collectedPackets);
}
Die Paketbenachrichtigung wird angezeigt, wenn der Stift auf der Digitalisiereroberfläche bewegt wird. In diesem Fall fügt die Anwendung dem Paketarray für das Stylus-Objekt neue StylusDownData hinzu. Dazu wird die Id-Eigenschaft des Stylus-Objekts als Schlüssel verwendet, um das Paketarray für den Tablettstift aus der Hashtabelle abzurufen. Die neuen Paketdaten werden dann in das abgerufene Array eingefügt.
public void Packets(RealTimeStylus sender, PacketsData data)
{
((ArrayList)(myPackets[data.Stylus.Id])).AddRange(data.GetData());
}
Die StylusUp-Benachrichtigung tritt auf, wenn der Stift die Digitizeroberfläche verlässt. Wenn diese Benachrichtigung auftritt, ruft das Beispiel das Paketarray für dieses Stylus-Objekt aus der Hashtabelle ab und entfernt es aus der Hashtabelle, da es nicht mehr benötigt wird, fügt die neuen Paketdaten hinzu und verwendet das Array von Paketdaten, um ein neues Stroke-Objekt zu erstellen. stroke
public void StylusUp(RealTimeStylus sender, StylusUpData data)
{
ArrayList collectedPackets = (ArrayList)myPackets[data.Stylus.Id];
myPackets.Remove(data.Stylus.Id);
collectedPackets.AddRange(data.GetData());
int[] packets = (int[])(collectedPackets.ToArray(typeof(int)));
TabletPropertyDescriptionCollection tabletProperties =
myRealTimeStylus.GetTabletPropertyDescriptionCollection(data.Stylus.TabletContextId);
Stroke stroke = myInk.CreateStroke(packets, tabletProperties);
if (stroke != null)
{
stroke.DrawingAttributes.Color = myDynamicRenderer.DrawingAttributes.Color;
stroke.DrawingAttributes.Width = myDynamicRenderer.DrawingAttributes.Width;
}
}
Ein Beispiel für eine stabilere Verwendung der RealTimeStylus-Klasse , einschließlich der Verwendung benutzerdefinierter Plug-Ins, finden Sie unter Beispiel für das RealTimeStylus-Plug-In.
Zugehörige Themen