Condividi tramite


Intercettazione dell'input dallo stilo

L'architettura System.Windows.Input.StylusPlugIns fornisce un meccanismo per implementare un controllo di basso livello sull'input Stylus e la creazione di oggetti di inchiostro digitale Stroke. La classe StylusPlugIn fornisce un meccanismo per implementare un comportamento personalizzato e applicarlo al flusso di dati provenienti dal dispositivo stilo per ottenere prestazioni ottimali.

Questo argomento contiene le sottosezioni seguenti:

Architettura

L'StylusPlugIn è l'evoluzione delle StylusInput API, descritte in Accesso e modifica dell'input penna.

Ogni UIElement ha una proprietà StylusPlugIns che è un StylusPlugInCollection. È possibile aggiungere un StylusPlugIn alla proprietà StylusPlugIns di un elemento per modificare i dati StylusPoint generati. StylusPoint dati sono costituiti da tutte le proprietà supportate dal digitalizzatore di sistema, inclusi i dati X e Y punto, nonché i dati PressureFactor.

Gli oggetti StylusPlugIn vengono inseriti direttamente nel flusso di dati provenienti dal dispositivo Stylus quando si aggiunge la StylusPlugIn alla proprietà StylusPlugIns. L'ordine in cui i plug-in vengono aggiunti alla raccolta StylusPlugIns determina l'ordine in cui riceveranno i dati StylusPoint. Ad esempio, se si aggiunge un plug-in di filtro che limita l'input a una determinata area e quindi si aggiunge un plug-in che riconosce i gesti mentre vengono eseguiti, il plug-in che riconosce i gesti riceverà dati filtrati StylusPoint.

Implementazione di plug-in per stilo digitale

Per implementare un plug-in, derivare una classe da StylusPlugIn. Questa classe viene applicata al flusso di dati man mano che proviene dal Stylus. In questa classe è possibile modificare i valori dei dati StylusPoint.

Attenzione

Se un StylusPlugIn genera o causa un'eccezione, l'applicazione verrà chiusa. È consigliabile testare accuratamente i controlli che utilizzano un StylusPlugIn e usare un controllo solo se si è certi che il StylusPlugIn non genererà un'eccezione.

Nell'esempio seguente viene illustrato un plug-in che limita l'input dello stilo modificando i valori X e Y nei dati StylusPoint man mano che provengono dal dispositivo Stylus.

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

Aggiungere il plug-in a un InkCanvas

Il modo più semplice per usare il plug-in personalizzato consiste nell'implementare una classe che deriva da InkCanvas e aggiungerla alla proprietà StylusPlugIns.

Nell'esempio seguente viene illustrato un InkCanvas personalizzato che filtra l'inchiostro.

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

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

Se si aggiunge un FilterInkCanvas all'applicazione ed eseguirla, si noterà che l'inchiostro non è limitato a una regione finché l'utente non completa una pennellata. Il motivo è che InkCanvas ha una proprietà DynamicRenderer, che è un StylusPlugIn ed è già un membro della collezione StylusPlugIns. Il StylusPlugIn personalizzato aggiunto alla raccolta StylusPlugIns riceve i dati StylusPoint dopo che DynamicRenderer ha ricevuto i dati. Di conseguenza, i dati di StylusPoint non verranno filtrati fino a quando l'utente non solleva la penna per terminare un tratto. Per filtrare l'inchiostro mentre l'utente lo disegna, è necessario inserire il FilterPlugin prima del DynamicRenderer.

Il codice C# seguente illustra un InkCanvas personalizzato che filtra l'inchiostro mentre viene disegnato.

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

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

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

Conclusione

Derivando le proprie classi StylusPlugIn e inserendole nelle raccolte StylusPlugInCollection, è possibile migliorare notevolmente il comportamento dell'inchiostro digitale. È possibile accedere ai dati StylusPoint man mano che vengono generati, offrendo la possibilità di personalizzare l'input Stylus. Poiché si ha un accesso di basso livello ai dati StylusPoint, è possibile implementare la raccolta di inchiostro e l'elaborazione con prestazioni ottimali per la vostra applicazione.

Vedere anche