共用方式為


攔截手寫筆的輸入

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

本主題包含下列子章節:

架構

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

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

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

實作手寫筆外掛程式

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

警告

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

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

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 資料具有低層級存取權,因此您可以實作筆跡集合,並以應用程式的最佳效能轉譯。

另請參閱