Compartilhar via


Interceptando a entrada da caneta

A arquitetura System.Windows.Input.StylusPlugIns fornece um mecanismo para implementar controle de baixo nível sobre a entrada Stylus e a criação de objetos de tinta digital Stroke. A classe StylusPlugIn fornece um mecanismo para implementar o comportamento personalizado e aplicá-lo ao fluxo de dados provenientes do dispositivo stylus para o desempenho ideal.

Este tópico contém as seguintes subseções:

Arquitetura

O StylusPlugIn é a evolução das APIs de StylusInput, descritas em Acessando e Manipulando Entrada de Caneta.

Cada UIElement tem uma propriedade StylusPlugIns que é uma StylusPlugInCollection. Você pode adicionar um StylusPlugIn à propriedade StylusPlugIns de um elemento para manipular StylusPoint dados conforme eles são gerados. Os dados StylusPoint consistem de todas as propriedades compatíveis com o digitalizador do sistema, incluindo os dados de ponto X e Y, bem como os dados PressureFactor.

Seus objetos StylusPlugIn são inseridos diretamente no fluxo de dados provenientes do dispositivo Stylus quando você adiciona o StylusPlugIn à propriedade StylusPlugIns. A ordem na qual os plug-ins são adicionados à coleção StylusPlugIns determina a ordem na qual eles receberão dados de StylusPoint. Por exemplo, se você adicionar um plug-in de filtro que restringe a entrada a uma determinada região e, em seguida, adicionar um plug-in que reconhece gestos à medida que são gravados, o plug-in que reconhece gestos receberá dados StylusPoint filtrados.

Implementando plug-ins Stylus

Para implementar um plug-in, derive uma classe de StylusPlugIn. Essa classe é aplicada ao fluxo de dados à medida que ele vem do Stylus. Nesta classe, você pode modificar os valores dos dados de StylusPoint.

Cuidado

Se um StylusPlugIn gerar ou causar uma exceção, o aplicativo será fechado. Você deve testar completamente os controles que consomem um StylusPlugIn e usar apenas um controle se tiver certeza de que o StylusPlugIn não gerará uma exceção.

O exemplo a seguir demonstra um plug-in que restringe a entrada de caneta modificando os valores X e Y nos dados de StylusPoint à medida que eles vêm do 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

Adicionando seu plug-in a um InkCanvas

A maneira mais fácil de usar seu plug-in personalizado é implementar uma classe derivada do InkCanvas e adicioná-la à propriedade StylusPlugIns.

O exemplo a seguir demonstra uma InkCanvas personalizada que filtra a tinta.

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

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

Se você adicionar um FilterInkCanvas ao seu aplicativo e executá-lo, observará que a tinta não fica restrita a uma região até que o usuário conclua um traço. Isso ocorre porque o InkCanvas tem uma propriedade DynamicRenderer, que é um StylusPlugIn e já é membro da coleção StylusPlugIns. O StylusPlugIn personalizado que você adicionou à coleção StylusPlugIns recebe os dados StylusPoint depois que DynamicRenderer recebe os dados. Como resultado, os dados StylusPoint não serão filtrados até que o usuário levante a caneta para concluir um traço. Para filtrar a tinta à medida que o usuário a desenha, você deve inserir o FilterPlugin antes do DynamicRenderer.

O código C# a seguir demonstra uma InkCanvas personalizada que filtra a tinta conforme ela é desenhada.

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

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

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

Conclusão

Ao derivar suas próprias classes de StylusPlugIn e inseri-las em coleções StylusPlugInCollection, você pode aprimorar muito o comportamento da tinta digital. Você tem acesso aos dados StylusPoint conforme eles são gerados, dando a oportunidade de personalizar a entrada Stylus. Como você tem acesso tão baixo aos dados de StylusPoint, você pode implementar a coleta e a renderização de tinta com o desempenho ideal para seu aplicativo.

Consulte também