Search code examples
c#wpfmulti-touchinkcanvas

WPF-InkCanvas StrokeErased event not firing when I used inkcanvas1.Strokes.Erase statement in C#


When I use inkcanvas1.EditingMode is InkCanvasEditingMode.EraseByPoint it is erasing and also StrokeErased event firing.
but when I erase stroke through inkcanvas1.Strokes.Erase(); function then StrokeErased event is not firing.
then how can I identify which stroke erased and which strokes are newly created.
consider on my inkcanvas thousands of strokes.
so I'm not able to maintain every added and removed strokes. is there any other event or any solution.

I have a below sample WPF Inkcanvas code
XAML Code

<Window x:Class="MyWhiteBoard.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyWhiteBoard"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="MainWindow" >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>
        <InkCanvas x:Name="inkcanvas1" Grid.Row="0" StrokeErased="inkcanvas1_StrokeErased" MouseMove="inkcanvas1_MouseMove"></InkCanvas>
        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Width="100" Height="50" Background="WhiteSmoke" Content="Draw" Click="drawInkClick"></Button>
            <Button Width="100" Height="50" Background="WhiteSmoke" Content="Erase by Point" Click="EraseByPointsClick"></Button>
            <Button Width="100" Height="50" Background="WhiteSmoke" Content="Stroke Erase" Click="StrokeEraseClick"></Button>
            <Button Width="100" Height="50" Background="WhiteSmoke" Content="clear all" Click="clearAllClick"></Button>
        </StackPanel>
    </Grid>
</Window>

Code Behind C# code

public partial class MainWindow : Window
    {
        private bool IsStrokeEraseCalled = false;
        public MainWindow()
        {
            InitializeComponent();
        }
        private void inkcanvas1_StrokeErased(object sender, RoutedEventArgs e)
        {
            // why this event is not calling when I use  
            //inkcanvas1.Strokes.Erase
        }
        private void EraseByPointsClick(object sender, RoutedEventArgs e)
        {
            inkcanvas1.EditingMode = InkCanvasEditingMode.EraseByPoint;
        }
        private void StrokeEraseClick(object sender, RoutedEventArgs e)
        {
            inkcanvas1.EditingMode = InkCanvasEditingMode.Select;
            IsStrokeEraseCalled = !IsStrokeEraseCalled;
        }
        private void clearAllClick(object sender, RoutedEventArgs e)
        {
            inkcanvas1.Strokes.Clear();
        }
        private void inkcanvas1_MouseMove(object sender, MouseEventArgs e)
        {
            if (IsStrokeEraseCalled)
            {
                Point currentPoint = e.GetPosition((IInputElement)sender);
                List<Point> enumrator = new List<Point>();
                enumrator.Add(new Point(currentPoint.X, currentPoint.Y));
                StylusShape EraseShape = (StylusShape)new RectangleStylusShape(100, 100, 0);
                inkcanvas1.Strokes.Erase(enumrator, EraseShape);
            }
        }

        private void drawInkClick(object sender, RoutedEventArgs e)
        {
            inkcanvas1.EditingMode = InkCanvasEditingMode.Ink;
        }
    }

Solution

  • Replace your StrokeEraseClick event with following code:

    private void StrokeEraseClick(object sender, RoutedEventArgs e)
        {
            inkcanvas1.EditingMode = InkCanvasEditingMode.EraseByPoint;
            inkcanvas1.EraserShape = new RectangleStylusShape(100, 100);
            var editMode = inkcanvas1.EditingMode;
            inkcanvas1.EditingMode = InkCanvasEditingMode.None;
            inkcanvas1.EditingMode = editMode;
        }      
    

    It will leave the current mode to InkCanvasEditingMode.EraseByPoint and allow you to erase defined area stokes. StrokeErased event will be fired every time you erase strokes using this approach.