Pregunta

After doing some research on subject I didn't find anything, so I'm sorry if the same question was already asked.

Task: make a colored track-line on Canvas after cursor, when the left mouse button is pressed (like brush in Paint).

Problem: I think using System.Windows.Shapes.Path is the best approach to doing this task. Code below works fine, except for one thing: if you try to move your cursor then change direction to the opposite (e.g. the value on X-axis increases, then decreases, but the value on Y-axis, stays constant), you will get an unexpected part of Line, corresponding to the previous direction.

I'm sorry for the tangled description of my problem, but I hope you will get it.

To make it easier for you to reproduce it on your machine I'm adding the solution.

Please, point out for my mistake if I did one!

C# using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes;

namespace WpfApplication3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    private Boolean Inserting;
    private Path path;
    private Boolean isFirstPoint;

    public MainWindow()
    {
        InitializeComponent();
        LolCanvas.IsHitTestVisible = true;
    }

    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (Inserting)
        {
            Point p = Mouse.GetPosition(LolCanvas);
            if (isFirstPoint)
            {
                PathFigure myPathFigure = new PathFigure();
                myPathFigure.StartPoint = new Point(p.X + 5, p.Y + 5);
                myPathFigure.Segments = new PathSegmentCollection();
                (path.Data as PathGeometry).Figures.Add(myPathFigure);
                isFirstPoint = false;
            }
            else
            {
                LineSegment myLineSegment = new LineSegment();
                myLineSegment.Point = new Point(p.X + 5, p.Y + 5);
                (path.Data as PathGeometry).Figures[0].Segments.Add(myLineSegment);
            }
        }
    }

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Inserting = true;
        path = new Path();
        path.Stroke = new SolidColorBrush(Colors.Red);
        path.StrokeThickness = 50;
        path.Data = new PathGeometry();
        (path.Data as PathGeometry).Figures = new PathFigureCollection();
        LolCanvas.Children.Add(path);
        isFirstPoint = true;
    }

    private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Inserting = false;
    }
}
}

Xaml:

<Window x:Class="WpfApplication3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Canvas x:Name="LolCanvas" MouseMove="Canvas_MouseMove" MouseDown="Canvas_MouseDown"   MouseUp="Canvas_MouseUp" Background="Black">
    </Canvas>
</Window>

Link to the application: http://ge.tt/99aSgyo/v/0?c

¿Fue útil?

Solución

Apparently this kind of behavior is correct for path. The problem appeared because of the angle between line parts. It was 180 degrees, so window couldn't render Path propertly in this place. I had two ways to defeat it: 1) Set IsSmoothJoin property to true for each line segment. 2) Make another Path object, when this kind of problem might occur

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top