简体   繁体   English

取消在WPF画布(C#)上绘制的线条

[英]Cancel a line drawn on a wpf canvas (C#)

I use the following code to draw line on a wpf canvas, and I'd like to be able to press a "cancel" button to erase the last line that was added. 我使用以下代码在wpf画布上绘制线条,并且我希望能够按下“取消”按钮以删除最后添加的线条。

private void Canvas_MouseDown_1(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    if (e.ButtonState == MouseButtonState.Pressed) {
        currentPoint = e.GetPosition(this);
    }
}

private void Canvas_MouseMove_1(object sender, System.Windows.Input.MouseEventArgs e) 
{
    SolidColorBrush brush = new SolidColorBrush(Colors.Red);
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        Line line = new Line();

        line.Stroke = brush;
        line.StrokeThickness = 3;
        line.X1 = currentPoint.X;
        line.Y1 = currentPoint.Y;
        line.X2 = e.GetPosition(this).X;
        line.Y2 = e.GetPosition(this).Y;

        currentPoint = e.GetPosition(this);

        paintSurface.Children.Add(line);
    }
}

The way I tried to do it is by removing children from the canvas (paintSurface), which seems to be the way to go. 我尝试这样做的方法是从画布(paintSurface)中删除孩子,这似乎是可行的方法。 However, when I draw a line, it is made of lots of small children lines (more like dots), and I only erase them one at a time. 但是,当我画一条线时,它是由许多小的子线组成的(更像是点),并且一次只能擦除一条。 Here is what this partial solution looks like : 这是部分解决方案的样子:

private void button5_Click(object sender, RoutedEventArgs e)
{
    if (paintSurface.Children.Count != 0)
        paintSurface.Children.RemoveAt(paintSurface.Children.Count - 1);
}

I would need to be able to get the index of the first child of every line I draw and store them, so I can erase all children after this one. 我需要能够获得绘制的每条线的第一个子项的索引并将其存储,因此我可以擦除此行之后的所有子项。 Any idea ? 任何想法 ? Thanks in advance ! 提前致谢 !

EDIT : 编辑:

I found a way to answer my problem, but I won't mark it as the answer as it's very ugly. 我找到了解决问题的方法,但由于它很丑陋,因此我不会将其标记为答案。 The best way would be, as Clemens suggested, to use Polylines (he describes how in a comment) : 就像克莱门斯建议的那样,最好的方法是使用折线(他在评论中进行了介绍):

On mouseDown I read the number of children on the canvas, on mouseUp I read it again to know the number of children my line created. 在mouseDown上,我读取了画布上的子代数,在mouseUp上,我再次读取了该数,以了解我的行创建的子代数。 I add this to a list, then when I press the cancel button, I delete as many children as the last element of my list and remove this element. 我将其添加到列表中,然后按“取消”按钮时,删除的孩子数与列表中的最后一个元素一样多,然后删除此元素。

It works like a charm though... 虽然它就像一个魅力...

The creation of all the tiny line segments is caused by the sample rate at which the mouse move is detected. 所有细线段的创建都是由检测到鼠标移动的采样率引起的。

A solution might be to guess what the user intended as a single line: 一个解决方案可能是猜测用户单行的意图:

  • by measuring the length of each tiny stroke 通过测量每个小笔画的长度
  • the angle between two neighboring lines 两条相邻线之间的角度
  • the time between the drawing of two neighboring lines 绘制两条相邻线之间的时间

If any of these surpass a certain threshold it could be a logical break between two lines. 如果这些值中的任何一个超过某个阈值,则可能是两行之间的逻辑中断。

Note that for measuring the time between two lines you will need to store the time somewhere, whereas the first two measurements can be done on any given sequence. 请注意,要测量两行之间的时间,您需要将时间存储在某处,而前两次测量可以在任何给定序列上进行。

Another way is to sample less often: 另一种方法是减少采样次数:

  • if the mouse didn't move that much, do not add a line yet unless the mouse changed direction 如果鼠标没有移动太多,请不要添加线条,除非鼠标改变了方向

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM