Freigeben über


Gewusst wie: Löschen von Freihandeingaben auf einem benutzerdefinierten Steuerelement

Durch IncrementalStrokeHitTester wird ermittelt, ob sich der gerade gezogene Strich mit einem anderen Strich überschneidet. Dadurch kann ein Steuerelement erstellt werden, mit dem Benutzer Teile eines Strichs auf die gleiche Art und Weise löschen können, wie bei einem InkCanvas-Steuerelement, wenn für EditingMode die Einstellung EraseByPoint festgelegt ist.

Beispiel

Im folgenden Beispiel wird ein benutzerdefiniertes Steuerelement erstellt, mit dem Benutzer Teile von Strichen löschen können. In diesem Beispiel wird ein Steuerelement erstellt, das bei seiner Initialisierung Freihandeingaben enthält. Informationen zum Erstellen eines Steuerelements, das Freihandeingaben erfasst, finden Sie unter Erstellen eines Freihandeingabesteuerelements.

Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Ink
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.IO

' This control initializes with ink already on it and allows the
' user to erase the ink with the tablet pen or mouse.

Public Class InkEraser
    Inherits Label
    Private eraseTester As IncrementalStrokeHitTester

    Private presenter As InkPresenter

    ' The base-64 encoded string that contains ink data 
    ' in ink serialized format (ISF).
    Private strokesString As String = _
         "ALwHAxdIEETLgIgERYQBGwIAJAFGhAEbAgAkAQUBOBkgMgkA9P8CAekiOkUzCQD4n" _
        & "wIBWiA6RTgIAP4DAAAAgH8RAACAPx8JEQAAAAAAAPA/CiUHh/A6N4HR0AivFX8Vs" _
        & "IfsiuyLSaIeDSLwabiHm0GgUDi+KZkACjsQh/A9t4IC5VJpfLhaIxyxXIh7Dncnh" _
        & "+6e7qODwoERlPAw8EpGoJAgh61IKjCYXBYDA4DAIHF67KIHAAojB4fwMteBn+RKB" _
        & "lziaIfwWTeCwePqbM8WgIeeQCDQOFRvcIAKNA+H8B8XgQHkUbjQTTnGuaZns3l4h" _
        & "/DWt4a0YKBBOA94D6HRCAiGnp5CS8LExMLB1tOgYIAKUBOH8KnXhU7lMold+tcbi" _
        & "kChkqu2EtPYxp9bmYCH8HDHg4ZhMIwRyMHH+4Jt8nleX8c0/D/AkYwxJGiHkkQgM" _
        & "Ch9CqcFhMDQCBwWAwuR2eAACmgdh/EpF4lA6XMUfhMXgMHgVDxBFpRKpZII5EINA" _
        & "OA64M+J4Lw1CIoAh/B2x4PS4bQodAopEI5IJBki4waEx2Qy+dy+ayHgleEmmHH8c" _
        & "e3MZOCGw5TWd3CwsHAwMCgRAEAgElKwOHZKBApaGIfxezeL0uN02N8IzwaGEpNIJ" _
        & "ZxHnELyOj0GfyuU6FgmhplIgIfwYgeDHeaI1vjOtZgcHgHAYb9hUCgEFgsPm1xnM" _
        & "ZkYhsnYJgZeZh4uAgCgnSBIOJv4OAgwCmkgh/GrR41X4dGoRJL9EKra5HKY7IZ3C" _
        & "4fj/M06olSoU8kkehUbh8jkMdCH8IJXhAXhMCk8JuNlmNyh0YiEumUwn2wMRxyHw" _
        & "2TzWmzeb02OzGKxMITwIhnrjzbb44zRhGEKRhCM4zrr6sQKXRWH8kuXkmPj0DiXC" _
        & "gcJbC9HZZgkKgUG4bLh3YrwJHAYw2CAh/CiN4Tq7DOZr4BB/AFtdOWW5P2h1Wkzv" _
        & "l4+YwqXf8d5fZ7ih51QKbB4LQrLAYDBIDABA4BO4nAICApvIIfy4BeXA2DRSrQlL" _
        & "oHHsYQ/KMXlsvl8rn8Xkcdg+G9NVaUWimUDYk9Ah/BoF4M0YBCqZPYqk8dwLf7hD" _
        & "YNBJFLKBNqZTqNubWshl9VoM1reFYZYQEBGUsDAwKEjYuDQKBgICBgCAgIOAg4nI" _
        & "8OACloSh/BFl4Gf/IOt6FXfF8F4ToPCZzlPwP4+B+DHmQO847rfDeCcG8eKh/EZV" _
        & "4i9eZt8A9nUF8VzxaUe5grl7YrPaHfpRKJNx4yHmUuj1vicwmMBEAjUVgKB61A="

    Public Sub New() 
        presenter = New InkPresenter()
        Me.Content = presenter

        ' Create a StrokeCollection the string and add it to
        Dim converter As New StrokeCollectionConverter()

        If converter.CanConvertFrom(GetType(String)) Then
            Dim newStrokes As StrokeCollection = converter.ConvertFrom(strokesString)

            presenter.Strokes.Clear()
            presenter.Strokes.Add(newStrokes)
        End If

    End Sub 'New

    Protected Overrides Sub OnStylusDown(ByVal e As StylusDownEventArgs) 

        MyBase.OnStylusDown(e)
        Dim points As StylusPointCollection = e.GetStylusPoints(Me)

        InitializeEraserHitTester(points)

    End Sub 'OnStylusDown

    Protected Overrides Sub OnMouseLeftButtonDown(ByVal e As MouseButtonEventArgs) 

        MyBase.OnMouseLeftButtonDown(e)

        If Not (e.StylusDevice Is Nothing) Then
            Return
        End If

        Dim pt As Point = e.GetPosition(Me)

        Dim collectedPoints As New StylusPointCollection(New Point() {pt})

        InitializeEraserHitTester(collectedPoints)

    End Sub 'OnMouseLeftButtonDown

    ' Get the IncrementalHitTester from the InkPresenter's 
    ' StrokeCollection and subscribe to its StrokeHitChanged event.
    Private Sub InitializeEraserHitTester(ByVal points As StylusPointCollection) 

        Dim eraserTip As New EllipseStylusShape(3, 3, 0)
        eraseTester = presenter.Strokes.GetIncrementalStrokeHitTester(eraserTip)
        AddHandler eraseTester.StrokeHit, AddressOf eraseTester_StrokeHit
        eraseTester.AddPoints(points)

    End Sub 'InitializeEraserHitTester


    Protected Overrides Sub OnStylusMove(ByVal e As StylusEventArgs) 
        Dim points As StylusPointCollection = e.GetStylusPoints(Me)

        AddPointsToEraserHitTester(points)

    End Sub 'OnStylusMove


    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs) 
        MyBase.OnMouseMove(e)

        If Not (e.StylusDevice Is Nothing) Then
            Return
        End If

        If e.LeftButton = MouseButtonState.Released Then
            Return
        End If

        Dim pt As Point = e.GetPosition(Me)

        Dim collectedPoints As New StylusPointCollection(New Point() {pt})

        AddPointsToEraserHitTester(collectedPoints)

    End Sub 'OnMouseMove


    ' Collect the StylusPackets as the stylus moves.
    Private Sub AddPointsToEraserHitTester(ByVal points As StylusPointCollection) 

        If eraseTester.IsValid Then
            eraseTester.AddPoints(points)
        End If

    End Sub 'AddPointsToEraserHitTester


    ' Unsubscribe from the StrokeHitChanged event when the
    ' user lifts the stylus.
    Protected Overrides Sub OnStylusUp(ByVal e As StylusEventArgs) 

        Dim points As StylusPointCollection = e.GetStylusPoints(Me)

        StopEraseHitTesting(points)

    End Sub 'OnStylusUp


    Protected Overrides Sub OnMouseLeftButtonUp(ByVal e As MouseButtonEventArgs) 

        MyBase.OnMouseLeftButtonUp(e)

        If Not (e.StylusDevice Is Nothing) Then
            Return
        End If

        Dim pt As Point = e.GetPosition(Me)

        Dim collectedPoints As New StylusPointCollection(New Point() {pt})

        StopEraseHitTesting(collectedPoints)

    End Sub 'OnMouseLeftButtonUp


    Private Sub StopEraseHitTesting(ByVal points As StylusPointCollection) 

        eraseTester.AddPoints(points)
        RemoveHandler eraseTester.StrokeHit, AddressOf eraseTester_StrokeHit
        eraseTester.EndHitTesting()

    End Sub 'StopEraseHitTesting

    ' When the stylus intersects a stroke, erase that part of
    ' the stroke.  When the stylus dissects a stoke, the 
    ' Stroke.Erase method returns a StrokeCollection that contains
    ' the two new strokes.
    Private Sub eraseTester_StrokeHit(ByVal sender As Object, ByVal args As StrokeHitEventArgs)

        Dim eraseResult As StrokeCollection = args.GetPointEraseResults()
        Dim strokesToReplace As New StrokeCollection()
        strokesToReplace.Add(args.HitStroke)

        ' Replace the old stroke with the new one.
        If eraseResult.Count > 0 Then
            presenter.Strokes.Replace(strokesToReplace, eraseResult)
        Else
            presenter.Strokes.Remove(strokesToReplace)
        End If

    End Sub 'eraseTester_StrokeHit
End Class 'InkEraser
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.IO;

// This control initializes with ink already on it and allows the
// user to erase the ink with the tablet pen or mouse.
public class InkEraser : Label
{
    IncrementalStrokeHitTester eraseTester;

    InkPresenter presenter;

    string strokesString =
        @"ALwHAxdIEETLgIgERYQBGwIAJAFGhAEbAgAkAQUBOBkgMgkA9P8CAekiOkUzCQD4n"
        + "wIBWiA6RTgIAP4DAAAAgH8RAACAPx8JEQAAAAAAAPA/CiUHh/A6N4HR0AivFX8Vs"
        + "IfsiuyLSaIeDSLwabiHm0GgUDi+KZkACjsQh/A9t4IC5VJpfLhaIxyxXIh7Dncnh"
        + "+6e7qODwoERlPAw8EpGoJAgh61IKjCYXBYDA4DAIHF67KIHAAojB4fwMteBn+RKB"
        + "lziaIfwWTeCwePqbM8WgIeeQCDQOFRvcIAKNA+H8B8XgQHkUbjQTTnGuaZns3l4h"
        + "/DWt4a0YKBBOA94D6HRCAiGnp5CS8LExMLB1tOgYIAKUBOH8KnXhU7lMold+tcbi"
        + "kChkqu2EtPYxp9bmYCH8HDHg4ZhMIwRyMHH+4Jt8nleX8c0/D/AkYwxJGiHkkQgM"
        + "Ch9CqcFhMDQCBwWAwuR2eAACmgdh/EpF4lA6XMUfhMXgMHgVDxBFpRKpZII5EINA"
        + "OA64M+J4Lw1CIoAh/B2x4PS4bQodAopEI5IJBki4waEx2Qy+dy+ayHgleEmmHH8c"
        + "e3MZOCGw5TWd3CwsHAwMCgRAEAgElKwOHZKBApaGIfxezeL0uN02N8IzwaGEpNIJ"
        + "ZxHnELyOj0GfyuU6FgmhplIgIfwYgeDHeaI1vjOtZgcHgHAYb9hUCgEFgsPm1xnM"
        + "ZkYhsnYJgZeZh4uAgCgnSBIOJv4OAgwCmkgh/GrR41X4dGoRJL9EKra5HKY7IZ3C"
        + "4fj/M06olSoU8kkehUbh8jkMdCH8IJXhAXhMCk8JuNlmNyh0YiEumUwn2wMRxyHw"
        + "2TzWmzeb02OzGKxMITwIhnrjzbb44zRhGEKRhCM4zrr6sQKXRWH8kuXkmPj0DiXC"
        + "gcJbC9HZZgkKgUG4bLh3YrwJHAYw2CAh/CiN4Tq7DOZr4BB/AFtdOWW5P2h1Wkzv"
        + "l4+YwqXf8d5fZ7ih51QKbB4LQrLAYDBIDABA4BO4nAICApvIIfy4BeXA2DRSrQlL"
        + "oHHsYQ/KMXlsvl8rn8Xkcdg+G9NVaUWimUDYk9Ah/BoF4M0YBCqZPYqk8dwLf7hD"
        + "YNBJFLKBNqZTqNubWshl9VoM1reFYZYQEBGUsDAwKEjYuDQKBgICBgCAgIOAg4nI"
        + "8OACloSh/BFl4Gf/IOt6FXfF8F4ToPCZzlPwP4+B+DHmQO847rfDeCcG8eKh/EZV"
        + "4i9eZt8A9nUF8VzxaUe5grl7YrPaHfpRKJNx4yHmUuj1vicwmMBEAjUVgKB61A=";

    public InkEraser()
    {
        presenter = new InkPresenter();
        this.Content = presenter;

        // Create a StrokeCollection the string and add it to
        StrokeCollectionConverter converter =
            new StrokeCollectionConverter();

        if (converter.CanConvertFrom(typeof(string)))
        {
            StrokeCollection newStrokes =
                converter.ConvertFrom(strokesString) as StrokeCollection;
            presenter.Strokes.Clear();
            presenter.Strokes.Add(newStrokes);
        }

    }


    protected override void OnStylusDown(StylusDownEventArgs e)
    {
        base.OnStylusDown(e);
        StylusPointCollection points = e.GetStylusPoints(this);

        InitializeEraserHitTester(points);

    }

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);

        if (e.StylusDevice != null)
        {
            return;
        }

        Point pt = e.GetPosition(this);

        StylusPointCollection collectedPoints = new StylusPointCollection(new Point[] { pt });

        InitializeEraserHitTester(collectedPoints);
    }

    // Prepare to collect stylus packets. Get the 
    // IncrementalHitTester from the InkPresenter's 
    // StrokeCollection and subscribe to its StrokeHitChanged event.
    private void InitializeEraserHitTester(StylusPointCollection points)
    {
        EllipseStylusShape eraserTip = new EllipseStylusShape(3, 3, 0);
        eraseTester =
            presenter.Strokes.GetIncrementalStrokeHitTester(eraserTip);
        eraseTester.StrokeHit += new StrokeHitEventHandler(eraseTester_StrokeHit);
        eraseTester.AddPoints(points);
    }

    protected override void OnStylusMove(StylusEventArgs e)
    {
        StylusPointCollection points = e.GetStylusPoints(this);

        AddPointsToEraserHitTester(points);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        if (e.StylusDevice != null)
        {
            return;
        }

        if (e.LeftButton == MouseButtonState.Released)
        {
            return;
        }

        Point pt = e.GetPosition(this);

        StylusPointCollection collectedPoints = new StylusPointCollection(new Point[] { pt });

        AddPointsToEraserHitTester(collectedPoints);
    }

    // Collect the StylusPackets as the stylus moves.
    private void AddPointsToEraserHitTester(StylusPointCollection points)
    {
        if (eraseTester.IsValid)
        {
            eraseTester.AddPoints(points);
        }
    }

    // Unsubscribe from the StrokeHitChanged event when the
    // user lifts the stylus.
    protected override void OnStylusUp(StylusEventArgs e)
    {
        StylusPointCollection points = e.GetStylusPoints(this);

        StopEraseHitTesting(points);
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonUp(e);

        if (e.StylusDevice != null)
        {
            return;
        }

        Point pt = e.GetPosition(this);

        StylusPointCollection collectedPoints = new StylusPointCollection(new Point[] { pt });

        StopEraseHitTesting(collectedPoints);
    }

    private void StopEraseHitTesting(StylusPointCollection points)
    {
        eraseTester.AddPoints(points);
        eraseTester.StrokeHit -= new
            StrokeHitEventHandler(eraseTester_StrokeHit);
        eraseTester.EndHitTesting();
    }


    // When the stylus intersects a stroke, erase that part of
    // the stroke.  When the stylus dissects a stoke, the 
    // Stroke.Erase method returns a StrokeCollection that contains
    // the two new strokes.
    void eraseTester_StrokeHit(object sender,
        StrokeHitEventArgs args)
    {
        StrokeCollection eraseResult =
            args.GetPointEraseResults();
        StrokeCollection strokesToReplace = new StrokeCollection();
        strokesToReplace.Add(args.HitStroke);

        // Replace the old stroke with the new one.
        if (eraseResult.Count > 0)
        {
            presenter.Strokes.Replace(strokesToReplace, eraseResult);
        }
        else
        {
            presenter.Strokes.Remove(strokesToReplace);
        }
    }
}