Przechwytywanie sygnału wejściowego z rysika
Architektura System.Windows.Input.StylusPlugIns zapewnia mechanizm implementowania kontroli niskiego poziomu nad danymi wejściowymi Stylus oraz tworzeniem cyfrowych obiektów Stroke atramentu cyfrowego. Klasa StylusPlugIn udostępnia mechanizm, który pozwala na implementację niestandardowego zachowania i zastosowanie go do strumieni danych pochodzących z urządzenia rysika, aby osiągnąć optymalną wydajność.
Ten temat zawiera następujące podsekcje:
Architektura
StylusPlugIn to ewolucja API StylusInput, opisanych w Uzyskiwanie dostępu i manipulowanie danymi wejściowymi pióra.
Każdy UIElement ma właściwość StylusPlugIns, która jest StylusPlugInCollection. Możesz dodać StylusPlugIn do właściwości StylusPlugIns elementu, aby manipulować danymi StylusPoint podczas ich generowania. StylusPoint dane składają się ze wszystkich właściwości obsługiwanych przez cyfrowy system, w tym dane punktów X i Y, a także dane PressureFactor.
Obiekty StylusPlugIn są wstawiane bezpośrednio do strumienia danych pochodzących z urządzenia Stylus podczas dodawania StylusPlugIn do właściwości StylusPlugIns. Kolejność dodawania wtyczek do kolekcji StylusPlugIns określa kolejność odbierania StylusPoint danych. Jeśli na przykład dodasz wtyczkę filtru, która ogranicza dane wejściowe do określonego regionu, a następnie dodaj wtyczkę, która rozpoznaje gesty podczas ich zapisywania, wtyczka, która rozpoznaje gesty, otrzyma przefiltrowane dane StylusPoint.
Implementowanie plug-inów Stylus
Aby zaimplementować wtyczkę, należy utworzyć klasę z StylusPlugIn. Ta klasa jest stosowana do strumienia danych, który napływa z Stylus. W tej klasie można modyfikować wartości danych StylusPoint.
Ostrożność
Jeśli StylusPlugIn zgłasza lub powoduje wyjątek, aplikacja zostanie zamknięta. Należy dokładnie przetestować kontrolki korzystające z StylusPlugIn i używać tylko kontrolki, jeśli masz pewność, że StylusPlugIn nie zgłosi wyjątku.
W poniższym przykładzie pokazano wtyczkę, która ogranicza wejście z rysika, modyfikując wartości X i Y w danych StylusPoint, gdy pochodzą one z urządzenia 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
Dodawanie wtyczki do aplikacji InkCanvas
Najprostszym sposobem użycia niestandardowej wtyczki jest zaimplementowanie klasy pochodzącej z usługi InkCanvas i dodanie jej do właściwości StylusPlugIns.
W poniższym przykładzie pokazano niestandardowy InkCanvas, który filtruje atrament.
public class FilterInkCanvas : InkCanvas
{
FilterPlugin filter = new FilterPlugin();
public FilterInkCanvas()
: base()
{
this.StylusPlugIns.Add(filter);
}
}
Jeśli dodasz FilterInkCanvas
do aplikacji i uruchomisz ją, zauważysz, że atrament nie jest ograniczony do regionu, dopóki użytkownik nie zakończy pociągnięcia. Jest to spowodowane tym, że InkCanvas ma właściwość DynamicRenderer, która jest StylusPlugIn i jest już członkiem kolekcji StylusPlugIns. Niestandardowy StylusPlugIn dodany do kolekcji StylusPlugIns odbiera dane StylusPoint po tym, jak DynamicRenderer odbierze dane. W rezultacie dane StylusPoint nie będą filtrowane aż do momentu, gdy użytkownik podniesie pióro, kończąc pociągnięcie. Aby odfiltrować atrament, gdy użytkownik go rysuje, należy wstawić FilterPlugin
przed DynamicRenderer.
Poniższy kod w języku C# demonstruje niestandardowy InkCanvas, który filtruje atrament w trakcie rysowania.
public class DynamicallyFilteredInkCanvas : InkCanvas
{
FilterPlugin filter = new FilterPlugin();
public DynamicallyFilteredInkCanvas()
: base()
{
int dynamicRenderIndex =
this.StylusPlugIns.IndexOf(this.DynamicRenderer);
this.StylusPlugIns.Insert(dynamicRenderIndex, filter);
}
}
Konkluzja
Wyprowadzając własne klasy StylusPlugIn i wstawiając je do kolekcji StylusPlugInCollection, możesz znacznie poprawić zachowanie cyfrowego atramentu. Masz dostęp do danych StylusPoint generowanych w miarę ich generowania, co daje możliwość dostosowania Stylus danych wejściowych. Ponieważ masz tak ograniczony dostęp do danych StylusPoint, możesz zaimplementować zbieranie tuszu i renderowanie z optymalną wydajnością dla swojej aplikacji.
Zobacz też
- Zaawansowana obsługa tuszu
- uzyskiwanie dostępu do danych wejściowych pióra i manipulowanie nimi
.NET Desktop feedback