Fånga upp indata från pennan

Arkitekturen System.Windows.Input.StylusPlugIns ger en mekanism för att implementera detaljkontroll över Stylus indata och skapa digitala bläckobjekt Stroke. Klassen StylusPlugIn tillhandahåller en mekanism för att implementera anpassat beteende och tillämpa den på dataströmmen som kommer från pennans enhet för optimala prestanda.

Det här avsnittet innehåller följande underavsnitt:

Arkitektur

StylusPlugIn är utvecklingen av API:erna StylusInput, som beskrivs i Åtkomst och Hantering av Penninmatning.

Varje UIElement har egenskapen StylusPlugIns som är en StylusPlugInCollection. Du kan addera StylusPlugIn till ett elements egenskap StylusPlugIns för att manipulera StylusPoint-data när det genereras. StylusPoint-data består av alla egenskaper som stöds av systemets digitaliserare, inklusive X och Y punktdata samt PressureFactor-data.

Dina StylusPlugIn objekt infogas direkt i dataströmmen som kommer från den Stylus enheten när du lägger till StylusPlugIn i egenskapen StylusPlugIns. Ordningen i vilken plugin-program läggs till i StylusPlugIns-samlingen avgör i vilken ordning de ska ta emot StylusPoint data. Om du till exempel lägger till ett filter-plugin-program som begränsar indata till en viss region och sedan lägger till ett plugin-program som identifierar gester när de skrivs, kommer plugin-programmet som identifierar gester att ta emot filtrerade StylusPoint data.

Implementera Stylus-plugins

Om du vill implementera ett plugin-program härleder du en klass från StylusPlugIn. Den här klassen tillämpas på dataströmmen som den kommer in från Stylus. I den här klassen kan du ändra värdena för StylusPoint data.

Försiktighet

Om en StylusPlugIn utlöser eller orsakar ett undantag stängs programmet. Du bör noggrant testa kontroller som använder en StylusPlugIn och endast använda en kontroll om du är säker på att StylusPlugIn inte utlöser ett undantag.

I följande exempel visas ett insticksprogram som begränsar inmatningen från pekpennan genom att ändra värdena för X och Y i StylusPoint-datan när de kommer från Stylus-enheten.

using System;
using System.Windows.Media;
using System.Windows;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Input;
using System.Windows.Ink;
Imports System.Windows.Media
Imports System.Windows
Imports System.Windows.Input.StylusPlugIns
Imports System.Windows.Input
Imports System.Windows.Ink
// A StylusPlugin that restricts the input area.
class FilterPlugin : StylusPlugIn
{
    protected override void OnStylusDown(RawStylusInput rawStylusInput)
    {
        // Call the base class before modifying the data.
        base.OnStylusDown(rawStylusInput);

        // Restrict the stylus input.
        Filter(rawStylusInput);
    }

    protected override void OnStylusMove(RawStylusInput rawStylusInput)
    {
        // Call the base class before modifying the data.
        base.OnStylusMove(rawStylusInput);

        // Restrict the stylus input.
        Filter(rawStylusInput);
    }

    protected override void OnStylusUp(RawStylusInput rawStylusInput)
    {
        // Call the base class before modifying the data.
        base.OnStylusUp(rawStylusInput);

        // Restrict the stylus input
        Filter(rawStylusInput);
    }

    private void Filter(RawStylusInput rawStylusInput)
    {
        // Get the StylusPoints that have come in.
        StylusPointCollection stylusPoints = rawStylusInput.GetStylusPoints();

        // Modify the (X,Y) data to move the points
        // inside the acceptable input area, if necessary.
        for (int i = 0; i < stylusPoints.Count; i++)
        {
            StylusPoint sp = stylusPoints[i];
            if (sp.X < 50) sp.X = 50;
            if (sp.X > 250) sp.X = 250;
            if (sp.Y < 50) sp.Y = 50;
            if (sp.Y > 250) sp.Y = 250;
            stylusPoints[i] = sp;
        }

        // Copy the modified StylusPoints back to the RawStylusInput.
        rawStylusInput.SetStylusPoints(stylusPoints);
    }
}
' A StylusPlugin that restricts the input area.
Class FilterPlugin
    Inherits StylusPlugIn

    Protected Overrides Sub OnStylusDown(ByVal rawStylusInput As RawStylusInput)
        ' Call the base class before modifying the data.
        MyBase.OnStylusDown(rawStylusInput)

        ' Restrict the stylus input.
        Filter(rawStylusInput)

    End Sub


    Protected Overrides Sub OnStylusMove(ByVal rawStylusInput As RawStylusInput)
        ' Call the base class before modifying the data.
        MyBase.OnStylusMove(rawStylusInput)

        ' Restrict the stylus input.
        Filter(rawStylusInput)

    End Sub


    Protected Overrides Sub OnStylusUp(ByVal rawStylusInput As RawStylusInput)
        ' Call the base class before modifying the data.
        MyBase.OnStylusUp(rawStylusInput)

        ' Restrict the stylus input
        Filter(rawStylusInput)

    End Sub


    Private Sub Filter(ByVal rawStylusInput As RawStylusInput)
        ' Get the StylusPoints that have come in.
        Dim stylusPoints As StylusPointCollection = rawStylusInput.GetStylusPoints()

        ' Modify the (X,Y) data to move the points 
        ' inside the acceptable input area, if necessary.
        Dim i As Integer
        For i = 0 To stylusPoints.Count - 1
            Dim sp As StylusPoint = stylusPoints(i)
            If sp.X < 50 Then
                sp.X = 50
            End If
            If sp.X > 250 Then
                sp.X = 250
            End If
            If sp.Y < 50 Then
                sp.Y = 50
            End If
            If sp.Y > 250 Then
                sp.Y = 250
            End If
            stylusPoints(i) = sp
        Next i

        ' Copy the modified StylusPoints back to the RawStylusInput.
        rawStylusInput.SetStylusPoints(stylusPoints)

    End Sub
End Class

Att lägga till insticksprogrammet till en InkCanvas

Det enklaste sättet att använda ditt anpassade plugin-program är att implementera en klass som härleds från InkCanvas och lägga till den i egenskapen StylusPlugIns.

I följande exempel visas en anpassad InkCanvas som filtrerar bläcket.

public class FilterInkCanvas : InkCanvas
{
    FilterPlugin filter = new FilterPlugin();

    public FilterInkCanvas()
        : base()
    {
        this.StylusPlugIns.Add(filter);
    }
}

Om du lägger till en FilterInkCanvas i ditt program och kör den ser du att pennanteckningen inte är begränsad till en region förrän användaren har slutfört en stroke. Det beror på att InkCanvas har en DynamicRenderer egenskap, som är en StylusPlugIn och redan är medlem i StylusPlugIns kollektion. Den anpassade StylusPlugIn som du lade till i StylusPlugIns-samlingen tar emot data från StylusPoint efter att DynamicRenderer har tagit emot data. Därför filtreras inte StylusPoint data förrän användaren lyfter pennan för att avsluta ett streck. Om du vill filtrera pennanteckningen när användaren ritar den måste du infoga FilterPlugin före DynamicRenderer.

Följande C#-kod visar en anpassad InkCanvas som filtrerar pennanteckningen när den ritas.

public class DynamicallyFilteredInkCanvas : InkCanvas
{
    FilterPlugin filter = new FilterPlugin();

    public DynamicallyFilteredInkCanvas()
        : base()
    {
        int dynamicRenderIndex =
            this.StylusPlugIns.IndexOf(this.DynamicRenderer);

        this.StylusPlugIns.Insert(dynamicRenderIndex, filter);
    }
}

Slutsats

Genom att härleda dina egna StylusPlugIn-klasser och infoga dem i StylusPlugInCollection-samlingar kan du förbättra beteendet avsevärt för ditt digitala bläck. Du har åtkomst till StylusPoint data när de genereras, vilket ger dig möjlighet att anpassa Stylus indata. Eftersom du har sådan åtkomst på låg nivå till StylusPoint data kan du implementera inkinsamling och rendering med optimala prestanda för ditt program.

Se även