Michaël Polla
Michaël Polla

Reputation: 3971

How must I change my code to make more than one line shape?

I want to draw lines in a "touch" application in WPF and wrote the following code:

XAML (part):

<Canvas x:Name="MainCanvas"
            IsManipulationEnabled="True"
            TouchDown="MainCanvas_TouchDown" 
            TouchUp="MainCanvas_TouchUp">

C#:

public partial class MainWindow : Window
{
    Line myLine = new Line();

    public MainWindow()
    {
        InitializeComponent();
    }

    public void MainCanvas_TouchDown(object sender, TouchEventArgs e)
    {
        myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
        myLine.StrokeThickness = 2;
        // Line's starting point
        myLine.X1 = e.GetTouchPoint(this).Position.X;
        myLine.Y1 = e.GetTouchPoint(this).Position.Y;
    }

    public void MainCanvas_TouchUp(object sender, TouchEventArgs e)
    {
        // Line's ending point
        myLine.X2 = e.GetTouchPoint(this).Position.X;
        myLine.Y2 = e.GetTouchPoint(this).Position.Y;

        MainCanvas.Children.Add(myLine);


    }
}

With this, I'm able to draw only one line. If I try to draw another, the application crashes.

Upvotes: 3

Views: 278

Answers (2)

Micha&#235;l Polla
Micha&#235;l Polla

Reputation: 3971

Thanks to O. R. Mapper's answer, here's the solution. As he explains, for each line a new Line instance must be created.

public partial class MainWindow : Window
{
    List<Line> lines = new List<Line>();

    public void MainCanvas_TouchDown(object sender, TouchEventArgs e)
    {
        Line myLine = new Line();           
        myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
        myLine.StrokeThickness = 2;
        myLine.X1 = e.GetTouchPoint(this).Position.X;
        myLine.Y1 = e.GetTouchPoint(this).Position.Y;
        lines.Add(myLine);
    }

    public void MainCanvas_TouchUp(object sender, TouchEventArgs e)
    {
        lines[lines.Count - 1].X2 = e.GetTouchPoint(this).Position.X;
        lines[lines.Count - 1].Y2 = e.GetTouchPoint(this).Position.Y;
        MainCanvas.Children.Add(lines[lines.Count - 1]);
    }
}

Upvotes: 1

O. R. Mapper
O. R. Mapper

Reputation: 20710

For each line that you want to draw, you will have to create a new Line instance. In your current code, you have just one Line instance, but that instance represents exactly one displayed line.

Unlike other graphics toolkits where you use various objects to draw graphical elements onto a drawing surface step by step, WPF works like vector graphics: Each of the objects you use is a graphical element; for two identical graphical elements, you will need two objects with the same properties.

Therefore, when you add the same graphical object for the second time, in this line:

MainCanvas.Children.Add(myLine);

An exception will be thrown, because you can only add each graphical element once.

As you want to add an arbitrary number of lines, store your lines in a list and add a new line instance (i.e. instantiate the Line class and add your new line to the canvas) in the touch-down event. In the touch-up event, set the second point of the new instance (the last element in your list).

Please be aware that this is not about C#, it is about WPF. (In other words, a C# pro who has never worked with WPF will not be able to tell you, but a WPF developer who has never used C# (always VB.NET, for example) might help.

Upvotes: 2

Related Questions