在WPF中从Canvas中删除Line

时间:2023-01-24 12:23:54

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.

Hy家伙,我正在尝试删除按下按钮之前创建的Line。我也希望按下按钮删除该行。我的画布上有很多行,所以我尝试按名称选择删除它但是我失败了。我也试过Uid并没有工作。

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:

这是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 ?

有什么想法吗?

1 个解决方案

#1


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.

但是,从您发布的代码中,似乎确实存在一个明显的问题:i的值仅在删除行的代码之后递减,但似乎该变量包含要添加的下一行的索引值,而不是最近添加的。

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.

根据您在评论中的描述,听起来就像您最初建议的更改时,代码只是崩溃(即“程序直接退出”,如您所说)。由于您没有提供完整的代码示例,因此我无法实际测试任何建议的解决方案,但我强烈怀疑您看到的崩溃是由于代码尝试修改(从中删除元素) canvas1.Children集合,与枚举的集合相同。

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.

为了将来参考,这似乎是调试器的一个很好的场景。如果您只是在butonStergere_Click()方法中设置一个断点并逐步完成循环的每次迭代,寻找您希望删除的对象,那么当您找到该对象时为什么代码本身不是很明显的识别它。

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.

大多数错误都发生了,因为我们作为一名程序员已经做出了一些假设不成真的事情。然后找到错误的最好方法是使用调试器并检查我们所做的每个假设的有效性,直到找到差异为止。

#1


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.

但是,从您发布的代码中,似乎确实存在一个明显的问题:i的值仅在删除行的代码之后递减,但似乎该变量包含要添加的下一行的索引值,而不是最近添加的。

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.

根据您在评论中的描述,听起来就像您最初建议的更改时,代码只是崩溃(即“程序直接退出”,如您所说)。由于您没有提供完整的代码示例,因此我无法实际测试任何建议的解决方案,但我强烈怀疑您看到的崩溃是由于代码尝试修改(从中删除元素) canvas1.Children集合,与枚举的集合相同。

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.

为了将来参考,这似乎是调试器的一个很好的场景。如果您只是在butonStergere_Click()方法中设置一个断点并逐步完成循环的每次迭代,寻找您希望删除的对象,那么当您找到该对象时为什么代码本身不是很明显的识别它。

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.

大多数错误都发生了,因为我们作为一名程序员已经做出了一些假设不成真的事情。然后找到错误的最好方法是使用调试器并检查我们所做的每个假设的有效性,直到找到差异为止。