Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Sie können ein benutzerdefiniertes Steuerelement erstellen, das Freihandeingaben dynamisch und statisch rendert. Das bedeutet, dass die Eingabe gerendert wird, während der Benutzer einen Strich zieht, sodass der Stift den Strich scheinbar zeichnet. Außerdem wird die Eingabe angezeigt, nachdem sie dem Steuerelement per Tablettstift, durch Einfügen aus der Zwischenablage oder durch Laden aus einer Datei hinzugefügt wurde. Das Steuerelement muss DynamicRenderer verwenden, um Freihandeingaben dynamisch zu rendern. Zum statischen Rendern von Freihandeingaben müssen die Tablettstiftereignismethoden (OnStylusDown, OnStylusMove und OnStylusUp) überschrieben werden, um StylusPoint-Daten zu erfassen, Striche zu erstellen und sie dem InkPresenter (zum Rendern der Freihandeingabe auf dem Steuerelement) hinzuzufügen.
Dieses Thema enthält folgende Unterabschnitte:
Gewusst wie: Erfassen von Tablettstift-Punktdaten und Erstellen von Freihandstrichen
Gewusst wie: Aktivieren der Mauseingabe für das Steuerelement
Die Komponenten im Zusammenhang
Verwenden von zusätzlichen Plug-Ins und DynamicRenderers
Schlussfolgerung
Gewusst wie: Erfassen von Tablettstift-Punktdaten und Erstellen von Freihandstrichen
So erstellen Sie ein Steuerelement, das Freihandstriche erfasst und verwaltet
Leiten Sie eine Klasse von Control oder einer der Klassen ab, die von Control, z. B. Label, abgeleitet werden.
Imports System Imports System.Collections.Generic Imports System.Text Imports System.Windows.Ink Imports System.Windows.Input Imports System.Windows.Input.StylusPlugIns Imports System.Windows.Controls Imports System.Windows ... Class InkControl Inherits Label ... End Class 'StylusControlusing System; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Input.StylusPlugIns; using System.Windows.Controls; using System.Windows; ... class InkControl : Label { ... }Fügen Sie der Klasse InkPresenter hinzu, und legen Sie die Content-Eigenschaft auf den neuen InkPresenter fest.
Private ip As InkPresenter Public Sub New() ' Add an InkPresenter for drawing. ip = New InkPresenter() Me.Content = ip End SubInkPresenter ip; public InkControl() { // Add an InkPresenter for drawing. ip = new InkPresenter(); this.Content = ip; }Fügen Sie RootVisual von DynamicRenderer dem InkPresenter hinzu, indem Sie die AttachVisuals-Methode aufrufen und DynamicRenderer der StylusPlugIns-Sammlung hinzufügen. Dies ermöglicht InkPresenter das Anzeigen der Freihandeingaben, während die Tablettstift-Punktdaten vom Steuerelement erfasst werden.
Public Sub New() ... ' Add a dynamic renderer that ' draws ink as it "flows" from the stylus. dr = New DynamicRenderer() ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes) Me.StylusPlugIns.Add(dr) End Subpublic InkControl() { ... // Add a dynamic renderer that // draws ink as it "flows" from the stylus. dr = new DynamicRenderer(); ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes); this.StylusPlugIns.Add(dr); }Überschreiben Sie die OnStylusDown-Methode. Erfassen Sie in dieser Methode den Tablettstift durch einen Aufruf von Capture. Durch das Erfassen des Tablettstifts empfängt das Steuerelement auch dann StylusMove- und StylusUp-Ereignisse, wenn der Tablettstift außerhalb der Begrenzung des Steuerelements verwendet wird. Dies ist zwar nicht notwendig, wird jedoch im Hinblick auf die Benutzerfreundlichkeit empfohlen. Erstellen Sie eine neue StylusPointCollection, um StylusPoint-Daten zu erfassen. Fügen Sie schließlich den Anfangssatz der StylusPoint-Daten der StylusPointCollection hinzu.
Protected Overrides Sub OnStylusDown(ByVal e As StylusDownEventArgs) ' Capture the stylus so all stylus input is routed to this control. Stylus.Capture(Me) ' Allocate memory for the StylusPointsCollection and ' add the StylusPoints that have come in so far. stylusPoints = New StylusPointCollection() Dim eventPoints As StylusPointCollection = e.GetStylusPoints(Me, stylusPoints.Description) stylusPoints.Add(eventPoints) End Sub 'OnStylusDownprotected override void OnStylusDown(StylusDownEventArgs e) { // Capture the stylus so all stylus input is routed to this control. Stylus.Capture(this); // Allocate memory for the StylusPointsCollection and // add the StylusPoints that have come in so far. stylusPoints = new StylusPointCollection(); StylusPointCollection eventPoints = e.GetStylusPoints(this, stylusPoints.Description); stylusPoints.Add(eventPoints); }Überschreiben Sie die OnStylusMove-Methode, und fügen Sie die StylusPoint-Daten dem bereits erstellten StylusPointCollection-Objekt hinzu.
Protected Overrides Sub OnStylusMove(ByVal e As StylusEventArgs) If stylusPoints Is Nothing Then Return End If ' Add the StylusPoints that have come in since the ' last call to OnStylusMove. Dim newStylusPoints As StylusPointCollection = e.GetStylusPoints(Me, stylusPoints.Description) stylusPoints.Add(newStylusPoints) End Sub 'OnStylusMoveprotected override void OnStylusMove(StylusEventArgs e) { if (stylusPoints == null) { return; } // Add the StylusPoints that have come in since the // last call to OnStylusMove. StylusPointCollection newStylusPoints = e.GetStylusPoints(this, stylusPoints.Description); stylusPoints.Add(newStylusPoints); }Überschreiben Sie die OnStylusUp-Methode, und erstellen Sie einen neuen Stroke mithilfe der StylusPointCollection-Daten. Fügen Sie den neu erstellten Stroke der Strokes-Auflistung von InkPresenter hinzu, und heben Sie die Erfassung des Tablettstifts auf.
Protected Overrides Sub OnStylusUp(ByVal e As StylusEventArgs) ' Allocate memory for the StylusPointsCollection, if necessary. If stylusPoints Is Nothing Then Return End If ' Add the StylusPoints that have come in since the ' last call to OnStylusMove. Dim newStylusPoints As StylusPointCollection = e.GetStylusPoints(Me, stylusPoints.Description) stylusPoints.Add(newStylusPoints) ' Create a new stroke from all the StylusPoints since OnStylusDown. Dim stroke As New Stroke(stylusPoints) ' Add the new stroke to the Strokes collection of the InkPresenter. ip.Strokes.Add(stroke) ' Clear the StylusPointsCollection. stylusPoints = Nothing ' Release stylus capture. Stylus.Capture(Nothing) End Sub 'OnStylusUpprotected override void OnStylusUp(StylusEventArgs e) { if (stylusPoints == null) { return; } // Add the StylusPoints that have come in since the // last call to OnStylusMove. StylusPointCollection newStylusPoints = e.GetStylusPoints(this, stylusPoints.Description); stylusPoints.Add(newStylusPoints); // Create a new stroke from all the StylusPoints since OnStylusDown. Stroke stroke = new Stroke(stylusPoints); // Add the new stroke to the Strokes collection of the InkPresenter. ip.Strokes.Add(stroke); // Clear the StylusPointsCollection. stylusPoints = null; // Release stylus capture. Stylus.Capture(null); }
Gewusst wie: Aktivieren der Mauseingabe für das Steuerelement
Wenn Sie der Anwendung das vorherige Steuerelement hinzufügen, diese ausführen und die Maus als Eingabegerät verwenden, werden die Striche nicht beibehalten. So behalten Sie die mit einer Maus eingegebenen Striche bei
Überschreiben Sie OnMouseLeftButtonDown, und erstellen Sie eine neue StylusPointCollection. Rufen Sie die Mausposition zum Zeitpunkt des Auftretens des Ereignisses ab, und erstellen Sie mithilfe der Punktdaten einen StylusPoint. Fügen Sie dann den StylusPointzur StylusPointCollection hinzu.
Protected Overrides Sub OnMouseLeftButtonDown(ByVal e As MouseButtonEventArgs) MyBase.OnMouseLeftButtonDown(e) ' If a stylus generated this event, return. If Not (e.StylusDevice Is Nothing) Then Return End If ' Start collecting the points. stylusPoints = New StylusPointCollection() Dim pt As Point = e.GetPosition(Me) stylusPoints.Add(New StylusPoint(pt.X, pt.Y)) End Sub 'OnMouseLeftButtonDownprotected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); // If a stylus generated this event, return. if (e.StylusDevice != null) { return; } // Start collecting the points. stylusPoints = new StylusPointCollection(); Point pt = e.GetPosition(this); stylusPoints.Add(new StylusPoint(pt.X, pt.Y)); }Überschreiben Sie die OnMouseMove-Methode. Rufen Sie die Mausposition zu dem Zeitpunkt ab, als das Ereignis aufgetreten ist, und erstellen Sie mithilfe der Punktdaten einen StylusPoint. Fügen Sie den StylusPoint dem bereits erstellten StylusPointCollection-Objekt hinzu.
Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs) MyBase.OnMouseMove(e) ' If a stylus generated this event, return. If Not (e.StylusDevice Is Nothing) Then Return End If ' Don't collect points unless the left mouse button ' is down. If e.LeftButton = MouseButtonState.Released Then Return End If If stylusPoints Is Nothing Then Return End If Dim pt As Point = e.GetPosition(Me) stylusPoints.Add(New StylusPoint(pt.X, pt.Y)) End Sub 'OnMouseMoveprotected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); // If a stylus generated this event, return. if (e.StylusDevice != null) { return; } // Don't collect points unless the left mouse button // is down. if (e.LeftButton == MouseButtonState.Released || stylusPoints == null) { return; } Point pt = e.GetPosition(this); stylusPoints.Add(new StylusPoint(pt.X, pt.Y)); }Überschreiben Sie die OnMouseLeftButtonUp-Methode. Erstellen Sie einen neuen Stroke mithilfe der StylusPointCollection-Daten. Fügen Sie den neu erstellten Stroke der Strokes-Auflistung des InkPresenter hinzu.
Protected Overrides Sub OnMouseLeftButtonUp(ByVal e As MouseButtonEventArgs) MyBase.OnMouseLeftButtonUp(e) ' If a stylus generated this event, return. If Not (e.StylusDevice Is Nothing) Then Return End If If stylusPoints Is Nothing Then stylusPoints = New StylusPointCollection() End If Dim pt As Point = e.GetPosition(Me) stylusPoints.Add(New StylusPoint(pt.X, pt.Y)) ' Create a stroke and add it to the InkPresenter. Dim stroke As New Stroke(stylusPoints) stroke.DrawingAttributes = dr.DrawingAttributes ip.Strokes.Add(stroke) stylusPoints = Nothing End Sub 'OnMouseLeftButtonUpprotected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnMouseLeftButtonUp(e); // If a stylus generated this event, return. if (e.StylusDevice != null) { return; } if (stylusPoints == null) { return; } Point pt = e.GetPosition(this); stylusPoints.Add(new StylusPoint(pt.X, pt.Y)); // Create a stroke and add it to the InkPresenter. Stroke stroke = new Stroke(stylusPoints); stroke.DrawingAttributes = dr.DrawingAttributes; ip.Strokes.Add(stroke); stylusPoints = null; }
Die Komponenten im Zusammenhang
Das folgende Beispiel enthält ein benutzerdefiniertes Steuerelement, das Freihandeingaben erfasst, die Benutzer mit der Maus oder dem Tablettstift eingeben.
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Ink
Imports System.Windows.Input
Imports System.Windows.Input.StylusPlugIns
Imports System.Windows.Controls
Imports System.Windows
...
' A control for managing ink input
Class InkControl
Inherits Label
Private ip As InkPresenter
Private dr As DynamicRenderer
' The StylusPointsCollection that gathers points
' before Stroke from is created.
Private stylusPoints As StylusPointCollection = Nothing
Public Sub New()
' Add an InkPresenter for drawing.
ip = New InkPresenter()
Me.Content = ip
' Add a dynamic renderer that
' draws ink as it "flows" from the stylus.
dr = New DynamicRenderer()
ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes)
Me.StylusPlugIns.Add(dr)
Dim cdr As New CustomDynamicRenderer()
ip.AttachVisuals(cdr.RootVisual, cdr.DrawingAttributes)
Me.StylusPlugIns.Add(cdr)
End Sub 'New
Shared Sub New()
' Allow ink to be drawn only within the bounds of the control.
Dim owner As Type = GetType(InkControl)
ClipToBoundsProperty.OverrideMetadata(owner, New FrameworkPropertyMetadata(True))
End Sub 'New
Protected Overrides Sub OnStylusDown(ByVal e As StylusDownEventArgs)
' Capture the stylus so all stylus input is routed to this control.
Stylus.Capture(Me)
' Allocate memory for the StylusPointsCollection and
' add the StylusPoints that have come in so far.
stylusPoints = New StylusPointCollection()
Dim eventPoints As StylusPointCollection = e.GetStylusPoints(Me, stylusPoints.Description)
stylusPoints.Add(eventPoints)
End Sub 'OnStylusDown
Protected Overrides Sub OnStylusMove(ByVal e As StylusEventArgs)
If stylusPoints Is Nothing Then
Return
End If
' Add the StylusPoints that have come in since the
' last call to OnStylusMove.
Dim newStylusPoints As StylusPointCollection = e.GetStylusPoints(Me, stylusPoints.Description)
stylusPoints.Add(newStylusPoints)
End Sub 'OnStylusMove
Protected Overrides Sub OnStylusUp(ByVal e As StylusEventArgs)
' Allocate memory for the StylusPointsCollection, if necessary.
If stylusPoints Is Nothing Then
Return
End If
' Add the StylusPoints that have come in since the
' last call to OnStylusMove.
Dim newStylusPoints As StylusPointCollection = e.GetStylusPoints(Me, stylusPoints.Description)
stylusPoints.Add(newStylusPoints)
' Create a new stroke from all the StylusPoints since OnStylusDown.
Dim stroke As New Stroke(stylusPoints)
' Add the new stroke to the Strokes collection of the InkPresenter.
ip.Strokes.Add(stroke)
' Clear the StylusPointsCollection.
stylusPoints = Nothing
' Release stylus capture.
Stylus.Capture(Nothing)
End Sub 'OnStylusUp
Protected Overrides Sub OnMouseLeftButtonDown(ByVal e As MouseButtonEventArgs)
MyBase.OnMouseLeftButtonDown(e)
' If a stylus generated this event, return.
If Not (e.StylusDevice Is Nothing) Then
Return
End If
' Start collecting the points.
stylusPoints = New StylusPointCollection()
Dim pt As Point = e.GetPosition(Me)
stylusPoints.Add(New StylusPoint(pt.X, pt.Y))
End Sub 'OnMouseLeftButtonDown
Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
MyBase.OnMouseMove(e)
' If a stylus generated this event, return.
If Not (e.StylusDevice Is Nothing) Then
Return
End If
' Don't collect points unless the left mouse button
' is down.
If e.LeftButton = MouseButtonState.Released Then
Return
End If
If stylusPoints Is Nothing Then
Return
End If
Dim pt As Point = e.GetPosition(Me)
stylusPoints.Add(New StylusPoint(pt.X, pt.Y))
End Sub 'OnMouseMove
Protected Overrides Sub OnMouseLeftButtonUp(ByVal e As MouseButtonEventArgs)
MyBase.OnMouseLeftButtonUp(e)
' If a stylus generated this event, return.
If Not (e.StylusDevice Is Nothing) Then
Return
End If
If stylusPoints Is Nothing Then
stylusPoints = New StylusPointCollection()
End If
Dim pt As Point = e.GetPosition(Me)
stylusPoints.Add(New StylusPoint(pt.X, pt.Y))
' Create a stroke and add it to the InkPresenter.
Dim stroke As New Stroke(stylusPoints)
stroke.DrawingAttributes = dr.DrawingAttributes
ip.Strokes.Add(stroke)
stylusPoints = Nothing
End Sub 'OnMouseLeftButtonUp
End Class 'StylusControl
using System;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Controls;
using System.Windows;
...
// A control for managing ink input
class InkControl : Label
{
InkPresenter ip;
DynamicRenderer dr;
// The StylusPointsCollection that gathers points
// before Stroke from is created.
StylusPointCollection stylusPoints = null;
public InkControl()
{
// Add an InkPresenter for drawing.
ip = new InkPresenter();
this.Content = ip;
// Add a dynamic renderer that
// draws ink as it "flows" from the stylus.
dr = new DynamicRenderer();
ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes);
this.StylusPlugIns.Add(dr);
}
static InkControl()
{
// Allow ink to be drawn only within the bounds of the control.
Type owner = typeof(InkControl);
ClipToBoundsProperty.OverrideMetadata(owner,
new FrameworkPropertyMetadata(true));
}
protected override void OnStylusDown(StylusDownEventArgs e)
{
// Capture the stylus so all stylus input is routed to this control.
Stylus.Capture(this);
// Allocate memory for the StylusPointsCollection and
// add the StylusPoints that have come in so far.
stylusPoints = new StylusPointCollection();
StylusPointCollection eventPoints =
e.GetStylusPoints(this, stylusPoints.Description);
stylusPoints.Add(eventPoints);
}
protected override void OnStylusMove(StylusEventArgs e)
{
if (stylusPoints == null)
{
return;
}
// Add the StylusPoints that have come in since the
// last call to OnStylusMove.
StylusPointCollection newStylusPoints =
e.GetStylusPoints(this, stylusPoints.Description);
stylusPoints.Add(newStylusPoints);
}
protected override void OnStylusUp(StylusEventArgs e)
{
if (stylusPoints == null)
{
return;
}
// Add the StylusPoints that have come in since the
// last call to OnStylusMove.
StylusPointCollection newStylusPoints =
e.GetStylusPoints(this, stylusPoints.Description);
stylusPoints.Add(newStylusPoints);
// Create a new stroke from all the StylusPoints since OnStylusDown.
Stroke stroke = new Stroke(stylusPoints);
// Add the new stroke to the Strokes collection of the InkPresenter.
ip.Strokes.Add(stroke);
// Clear the StylusPointsCollection.
stylusPoints = null;
// Release stylus capture.
Stylus.Capture(null);
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
// If a stylus generated this event, return.
if (e.StylusDevice != null)
{
return;
}
// Start collecting the points.
stylusPoints = new StylusPointCollection();
Point pt = e.GetPosition(this);
stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// If a stylus generated this event, return.
if (e.StylusDevice != null)
{
return;
}
// Don't collect points unless the left mouse button
// is down.
if (e.LeftButton == MouseButtonState.Released ||
stylusPoints == null)
{
return;
}
Point pt = e.GetPosition(this);
stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
// If a stylus generated this event, return.
if (e.StylusDevice != null)
{
return;
}
if (stylusPoints == null)
{
return;
}
Point pt = e.GetPosition(this);
stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
// Create a stroke and add it to the InkPresenter.
Stroke stroke = new Stroke(stylusPoints);
stroke.DrawingAttributes = dr.DrawingAttributes;
ip.Strokes.Add(stroke);
stylusPoints = null;
}
}
Verwenden von zusätzlichen Plug-Ins und DynamicRenderers
Wie InkCanvas kann das benutzerdefinierte Steuerelement über benutzerdefinierte StylusPlugIn und zusätzliche DynamicRenderer-Objekte verfügen. Fügen Sie diese der StylusPlugIns-Auflistung hinzu. Die Reihenfolge der StylusPlugIn-Objekte in der StylusPlugInCollection wirkt sich auf die Anzeige der gerenderten Feihandeingaben aus. Angenommen, Sie verfügen über einen DynamicRenderer mit dem Namen dynamicRenderer und über ein benutzerdefiniertes StylusPlugIn mit dem Namen translatePlugin, das den Offset der Freihandeingabe vom Tablettstift berechnet. Wenn translatePlugin das erste StylusPlugIn in der StylusPlugInCollection ist und dynamicRenderer an zweiter Stelle steht, wird der Offset der Freihandeingabe berechnet, während der Benutzer den Stift bewegt. Wenn dynamicRenderer in der Reihenfolge an erster Stelle und translatePlugin an zweiter Stelle steht, wird der Offset der Freihandeingabe erst berechnet, wenn der Benutzer den Stift anhebt.
Schlussfolgerung
Sie können ein Steuerelement, das Freihandeingaben erfasst und rendert, durch Überschreiben der Tablettstiftereignis-Methoden erstellen. Wenn Sie ein benutzerdefiniertes Steuerelement erstellen, eigene StylusPlugIn-Klassen ableiten und in StylusPlugInCollection einfügen, können Sie praktisch jedes Verhalten bezüglich Freihandeingaben implementieren. Sie können auf die StylusPoint-Daten zugreifen, während sie erstellt werden. So können Sie Stylus-Eingaben anpassen und Ihrer Anwendung entsprechend auf dem Bildschirm rendern. Durch diesen Low-Level-Zugriff auf die StylusPoint-Daten können Sie das Erfassen und Rendern von Freihandeingaben mit optimaler Leistung für Ihre Anwendung implementieren.