攔截手寫筆的輸入

System.Windows.Input.StylusPlugIns 架構提供一種機制,可用來實作對輸入的低階控制 Stylus ,以及建立數位筆跡 Stroke 物件。 類別 StylusPlugIn 提供一種機制,可讓您實作自訂行為,並將其套用至來自手寫筆裝置的資料串流,以獲得最佳效能。

本主題包含下列子章節:

架構

StylusPlugIn是手寫筆 API 的 演進,如存取和操作手寫筆輸入 中所述

每個 都有 UIElement 一個 StylusPlugInsStylusPlugInCollection 屬性,其為 。 您可以將 新增 StylusPlugIn 至元素的 StylusPlugIns 屬性,以在產生資料時操作 StylusPoint 資料。 StylusPoint 資料是由系統數位板支援的所有屬性所組成,包括 XY 點資料,以及 PressureFactor 資料。

當您將 新增 StylusPlugInStylusPlugIns 屬性時,物件 StylusPlugIn 會直接插入來自 Stylus 裝置的資料串流中。 將外掛程式新增至 StylusPlugIns 集合的順序會決定其接收 StylusPoint 資料的順序。 例如,如果您新增篩選外掛程式來限制特定區域的輸入,然後新增可辨識筆勢的外掛程式,識別手勢的外掛程式將會收到篩選 StylusPoint 的資料。

實作手寫筆外掛程式

若要實作外掛程式,請從 StylusPlugIn 衍生類別。 這個類別會套用至 來自 Stylus 的資料資料流程。 在此類別中,您可以修改資料的值 StylusPoint

警告

StylusPlugIn如果 擲回或造成例外狀況,應用程式將會關閉。 您應該徹底測試取用 StylusPlugIn 的控制項,而且只有在您確定 StylusPlugIn 不會擲回例外狀況時,才使用 控制項。

下列範例示範外掛程式,其可藉由修改 X 來自 Stylus 裝置的資料中的 StylusPointY 值,來限制手寫筆輸入。

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

將外掛程式新增至 InkCanvas

使用自訂外掛程式最簡單的方式是實作衍生自 InkCanvas 的類別,並將其新增至 StylusPlugIns 屬性。

下列範例示範篩選筆跡的自訂 InkCanvas

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

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

如果您將 新增 FilterInkCanvas 至應用程式並加以執行,您會注意到筆跡不會限制為區域,直到使用者完成筆劃之後。 這是因為 InkCanvas 有 屬性 DynamicRenderer ,也就是 StylusPlugIn ,而且已經是集合的成員 StylusPlugIns 。 您加入至集合的 StylusPlugIns 自訂 StylusPlugIn 會在接收資料之後 DynamicRenderer 接收 StylusPoint 資料。 因此, StylusPoint 在使用者將手寫筆抬起以結束筆劃之前,才會篩選資料。 若要在使用者繪製筆跡時篩選筆跡,您必須在 之前 DynamicRenderer 插入 FilterPlugin

下列 C# 程式碼示範自訂 InkCanvas ,其會在繪製時篩選筆跡。

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

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

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

推論

藉由衍生您自己的 StylusPlugIn 類別並將其插入 StylusPlugInCollection 集合中,您可以大幅增強數位筆跡的行為。 您可以在產生資料時存取 StylusPoint 資料,讓您有機會自訂 Stylus 輸入。 由於您對資料具有如此低階的 StylusPoint 存取權,因此您可以實作筆跡集合,並以最佳效能呈現應用程式。

另請參閱