简体   繁体   中英

C# Draw polyline(s) on mouse move

I want to draw something on my canvas whenever drawing_mode and is_drawing booleans are on. Right now I am using a polyline list and BackgroundWorker for threading. My main problem is that my code only creates one polyline and the dots are ALWAYS connected. In other words I can stop drawing for a while but then wherever I click a new line connection is made with the previous one. The end result is that my canvas.Children only has one polyline element with all the points. Could anyone help me solve this? PS I am not very good with threading yet...

    private BackgroundWorker drawing_worker;

    private void drawing_worker_ProgressChanged(object sender, ProgressChangedEventArgs eventargs)
    {            

        Polyline polyline = new Polyline();
        polyline.Points = last_polyline.Points;
        canvas.Children.Remove(last_polyline);

        var pos = canvas_relative_pos;
        polyline.Points.Add(pos);
        polyline.Stroke = new SolidColorBrush(Colors.Black);
        polyline.StrokeThickness = 1;
        canvas.Children.Add(polyline);

        last_polyline = polyline;
    }

    private void drawing_worker_DoWork(object sender, DoWorkEventArgs eventargs)
    {
        while (drawing_mode_enabled && is_drawing)
        {
            drawing_worker.ReportProgress(0);
            Thread.Sleep(5);
            if (drawing_worker.CancellationPending) break;
        }
    }

    private void ContentControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (drawing_mode_enabled)
        {
            is_drawing = true;

            drawing_worker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true                   
            };

            drawing_worker.ProgressChanged += drawing_worker_ProgressChanged;
            drawing_worker.DoWork += drawing_worker_DoWork;
            drawing_worker.RunWorkerAsync();
        }
    }

You don't need a BackgroundWorker or any other asynchronous stuff to draw polylines on Canvas.

Just create a Canvas with a Background (so that it gets input events) and handlers for the MouseLeftButtonDown , MouseLeftButtonUp and MouseMove events:

<Canvas Background="Transparent"
        MouseLeftButtonDown="CanvasMouseLeftButtonDown"
        MouseLeftButtonUp="CanvasMouseLeftButtonUp"
        MouseMove="CanvasMouseMove"/>

In the mouse down handler create a new Polyline and add it to the Canvas. Also capture the mouse so that you get mouse move events even when the mouse cursor leaves the Canvas. In the mouse up handler release the mouse capture. Finally, in the mouse move handler, add points to the last polyline child of the Canvas.

private void CanvasMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var panel = (Panel)sender;
    var polyline = new Polyline
    {
        Stroke = Brushes.Black,
        StrokeThickness = 3
    };

    panel.Children.Add(polyline);
    panel.CaptureMouse();
}

private void CanvasMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    ((UIElement)sender).ReleaseMouseCapture();            
}

private void CanvasMouseMove(object sender, MouseEventArgs e)
{
    var panel = (Panel)sender;

    if (panel.IsMouseCaptured)
    {
        var polyline = panel.Children.OfType<Polyline>().Last();
        polyline.Points.Add(e.GetPosition(panel));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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