Interceptar entradas del lápiz óptico

La arquitectura System.Windows.Input.StylusPlugIns proporciona un mecanismo para implementar un control de bajo nivel sobre la entrada Stylus y la creación de objetos de entrada de lápiz digital Stroke. La clase StylusPlugIn proporciona un mecanismo para que implemente un comportamiento personalizado y lo aplique al flujo de datos procedentes del dispositivo del lápiz óptico para el rendimiento óptimo.

Este tema contiene las siguientes subsecciones:

Arquitectura

El StylusPlugIn es la evolución de las API StylusInput, que se describen en Acceso y manipulación de la entrada del lápiz.

Cada UIElement tiene una propiedad StylusPlugIns que es una StylusPlugInCollection. Puede agregar un StylusPlugIn a la propiedad StylusPlugIns de un elemento para manipular los datos de StylusPoint a medida que se generan. Los datos de StylusPoint constan de todas las propiedades admitidas por el digitalizador del sistema, incluidos los X y los datos de punto Y, así como los datos de PressureFactor.

Los objetos StylusPlugIn se insertan directamente en el flujo de datos procedentes del dispositivo Stylus cuando se agrega el StylusPlugIn a la propiedad StylusPlugIns. El orden en que se agregan complementos a la colección StylusPlugIns determina el orden en el que recibirán datos de StylusPoint. Por ejemplo, si agrega un complemento de filtro que restringe la entrada a una región determinada y, a continuación, agrega un complemento que reconoce los gestos a medida que se escriben, el complemento que reconoce los gestos recibirá datos filtrados de StylusPoint.

Implementación de complementos de lápiz óptico

Para implementar un complemento, derive una clase de StylusPlugIn. Esta clase se aplica al flujo de datos a medida que se agregan desde Stylus. En esta clase puede modificar los valores de los datos de StylusPoint.

Precaución

Si un StylusPlugIn tiene o produce una excepción, se cerrará la aplicación. Debe probar exhaustivamente los controles que consumen un StylusPlugIn y solo usar un control si está seguro de que el StylusPlugIn no producirá una excepción.

En el ejemplo siguiente se muestra un complemento que restringe la entrada del lápiz óptico modificando los valores X y Y de los datos StylusPoint a medida que se obtienen del 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

Agregar el complemento a InkCanvas

La manera más fácil de usar el complemento personalizado es implementar una clase que deriva de InkCanvas y agregarla a la propiedad StylusPlugIns.

En el ejemplo siguiente se muestra un InkCanvas personalizado que filtra la entrada de lápiz.

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

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

Si agrega un elemento FilterInkCanvas a la aplicación y lo ejecuta, observará que la entrada de lápiz no está restringida a una región hasta que el usuario complete un trazo. Esto se debe a que InkCanvas tiene una propiedad DynamicRenderer, que es un StylusPlugIn y ya es miembro de la colección StylusPlugIns. El StylusPlugIn personalizado que agregó a la colección StylusPlugIns recibe los datos de StylusPoint después de que DynamicRenderer reciba datos. Como resultado, los datos de StylusPoint no se filtrarán hasta después de que el usuario levante el lápiz para finalizar un trazo. Para filtrar la entrada de lápiz a medida que el usuario la dibuja, debe insertar el FilterPlugin antes de DynamicRenderer.

El siguiente código de C# muestra un InkCanvas personalizado que filtra la entrada de lápiz a medida que se dibuja.

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

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

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

Conclusión

Al derivar sus propias clases StylusPlugIn e insertarlas en colecciones StylusPlugInCollection, puede mejorar considerablemente el comportamiento de la entrada de lápiz digital. Tiene acceso a los datos de StylusPointa medida que se generan, lo que le da la oportunidad de personalizar la entrada de Stylus. Dado el acceso de bajo nivel a los datos de StylusPoint, podrá implementar la colección de entrada de lápiz y representarla con un rendimiento óptimo para la aplicación.

Vea también