user2671364
user2671364

Reputation: 33

Remove Line from Canvas in WPF

Hy guys, I'm trying to delete a Line previously created by button pressed. I also want the line to be deleted by button pressed. There are a large number of lines on my canvas, so I've tried selecting it by name to delete it but I failed. Also I tried by Uid and did not work.

Here is the code for the line created:

 private void butonAdaugare_Click(object sender, RoutedEventArgs e)
    {

        Linie1.Y2 = Linie1.Y2 + 21;
        Linie2.Y2 = Linie2.Y2 + 21;
        Linie3.Y2 = Linie3.Y2 + 21;
        Linie4.Y2 = Linie4.Y2 + 21;

        Line linienoua = new Line();
        linienoua.Uid = "LinieNoua" + i;
        linienoua.X1 = 10;
        linienoua.Y1 = Linie4.Y2;
        linienoua.X2 = 670;
        linienoua.Y2 = Linie4.Y2;
        linienoua.Visibility = System.Windows.Visibility.Visible;
        linienoua.Stroke = System.Windows.Media.Brushes.Black;
        linienoua.StrokeThickness = 1;
        canvas1.Children.Add(linienoua);

        i++;

        foreach (Line l in canvas1.Children.OfType<Line>())
        {
            for (int j = 2; j < 15; j++)
            {
                if (l.Name == "V" + j)
                    l.Y2 = l.Y2 + 21;
            }
        } 
    }

And this is the removal part by Uid:

    private void butonStergere_Click(object sender, RoutedEventArgs e)
    {

        if (Linie1.Y2 > 101 && Linie2.Y2 > 101 && Linie3.Y2 > 101 && Linie4.Y2 > 101)
        {
            Linie1.Y2 = Linie1.Y2 - 21;
            Linie2.Y2 = Linie2.Y2 - 21;
            Linie3.Y2 = Linie3.Y2 - 21;
            Linie4.Y2 = Linie4.Y2 - 21;
        }


        foreach (Line l in canvas1.Children.OfType<Line>())
        {
            if (l.Uid == "LinieNoua" + i)
                canvas1.Children.Remove(l);

            for (int j = 2; j < 15; j++)
            {
                if (l.Name == "V" + j && l.Y2 > 91)
                    l.Y2 = l.Y2 - 21;
            }
        }

        i--;           
    } 

Any thoughts on this ?

Upvotes: 0

Views: 3120

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70701

Without a good, minimal, complete code example, it is hard to provide an answer with a high level of confidence. You have left too much information out of your question to know for sure what the problem is.

However, from the code you did post, there does seem to be one obvious problem: the value of i is being decremented only after the code to remove the line, but it seems that variable contains the index value for the next line to be added, not the most recently-added one.

It seems likely to me that if you simply move the decrement to occur prior to the loop that finds and removes the object, it would work:

private void butonStergere_Click(object sender, RoutedEventArgs e)
{

    if (Linie1.Y2 > 101 && Linie2.Y2 > 101 && Linie3.Y2 > 101 && Linie4.Y2 > 101)
    {
        Linie1.Y2 = Linie1.Y2 - 21;
        Linie2.Y2 = Linie2.Y2 - 21;
        Linie3.Y2 = Linie3.Y2 - 21;
        Linie4.Y2 = Linie4.Y2 - 21;
    }

    i--;           
    Line lineToRemove = null;

    foreach (Line l in canvas1.Children.OfType<Line>())
    {
        if (l.Uid == "LinieNoua" + i)
        {
            lineToRemove = l;
        }

        for (int j = 2; j < 15; j++)
        {
            if (l.Name == "V" + j && l.Y2 > 91)
                l.Y2 = l.Y2 - 21;
        }
    }

    if (lineToRemove != null)
    {
        canvas1.Children.Remove(lineToRemove);
    }
} 

<edit>
From your description in the comments, it sounds like when you made my originally suggested change, the code simply crashed (i.e. "the program exits directly", as you put it). Since you didn't provide a complete code example, there is no way for me to actually test any proposed solution, but I strongly suspect the crash you are seeing is due to the fact that the code attempts to modify (remove an element from) the canvas1.Children collection, which is the same collection that is being enumerated.

I have edited the proposed code change to avoid performing that illegal operation. Instead, the element to remove is simply noted in a local variable, and it is removed at the end, after the enumeration of all of the children has completed.
</edit>

For future reference, this seems like an excellent scenario for a debugger. If you were to simply set a breakpoint in the butonStergere_Click() method and step through each iteration of the loop, looking for the object you expect to be removed, it would be readily apparent when you find that object why the code itself wasn't identifying it.

Most bugs happen because we as a programmer have made an assumption about something that turns out to not be true. The best way to find bugs then is to use a debugger and examine the validity of each and every assumption we made, until we find the discrepancy.

Upvotes: 1

Related Questions