Vb.net 删除另一个面板内的面板

Vb.net 删除另一个面板内的面板,vb.net,controls,panel,Vb.net,Controls,Panel,我有一个面板,里面依次有4个面板。内部面板被命名为“XXXX | 1 | A”、“XXXX | 1 | B”、“XXXX | 1 | C”和“XXXX | 1 | D”,您可以在最后一个字母中看到它们的区别 在这种情况下,我要做的是始终只删除标识为A和B的面板 这是我的代码。 如您所见,使用变量控制_编号,我知道内部有4个面板,但在进行排列时,它的读数仅为3,并且仅移除标识为B且未到达面板A的面板 你能给我解释一下你为什么不读这4个面板吗?对我来说,有什么想法可以让我完成这四个步骤吗 谢谢。首先

我有一个面板,里面依次有4个面板。内部面板被命名为“XXXX | 1 | A”、“XXXX | 1 | B”、“XXXX | 1 | C”和“XXXX | 1 | D”,您可以在最后一个字母中看到它们的区别

在这种情况下,我要做的是始终只删除标识为A和B的面板

这是我的代码。

如您所见,使用变量控制_编号,我知道内部有4个面板,但在进行排列时,它的读数仅为3,并且仅移除标识为B且未到达面板A的面板

你能给我解释一下你为什么不读这4个面板吗?对我来说,有什么想法可以让我完成这四个步骤吗


谢谢。

首先,您不能使用管道字符“|”重命名控件,因为设计器不允许这样做。 然而,在下面的示例中,我假设它是一个下划线字符“\u1”。 现在,如果在循环过程中更改了集合的维度,则在循环集合时,您将丢失新长度/维度之后(删除)的元素数。 因此,要做到这一点,您可以使用反向循环的技巧(将最大维度设置为0),在这种情况下,其余元素始终在循环中

下面的代码说明了我的意思

    For i As Integer = pb.Controls.Count - 1 To 0 Step -1
        If pb.Controls(i).Name Like "*_A" OrElse pb.Controls(i).Name Like "*_B" Then
            pb.Controls.Remove(pb.Controls(i))
        End If
    Next

在为每个循环使用
枚举列表时,切勿修改列表。在这种情况和许多其他情况下,简单的解决方案是将您想要的项目提取到一个单独的列表中,并在从原始列表中删除项目的同时循环该列表。因此,删除操作不会对正在枚举的列表产生影响。在您的情况下,可能是这样的:

Dim panels=pb.Controls。
(面板的)类型()。
其中(函数(pnl)pnl.Name.EndsWith(“| A”)或
pnl.Name.EndsWith(“|B”))。
ToArray()
对于面板中的每个pnl
pnl.Dispose()
下一个

调用
Dispose
将从其父控件中删除该控件并正确地处理它。如果只调用
Remove
,则不会释放该控件。除非您打算重用该控件,否则这是不好的。

控件的
Name
属性只是一个
字符串,因此任何内容都是允许的。不能在设计器中使用这样的名称,因为这也会导致使用相同名称声明字段,并且标识符中不允许使用管道。若你们在运行时创建控件,那个么并没有相应的字段,所以标识符的限制就不适用了。我将添加此作为详细信息。:)。很好的方法,你的上面。我喜欢它@G3nt_M3caj,简单易懂的回答,非常感谢您的时间和努力。@G3nt_M3caj,还有一个问题,我尝试执行两个标准,即A和B或C和D都可以擦除,当我执行A和B时,它会擦除,但当我执行C和D时,它会跳过它们,任何不同的标准都没有考虑到吗?@LARC只需在你的if条款中添加类似
“*\u C”
或类似
“*\u D”
,我将应用你的答案。非常感谢您花了这么多时间和精力。需要记住的一点是,为了创建次列表,首先枚举原始列表的全部内容,然后再枚举次列表。这确实使这一选择的效率低于另一种选择,但这种差异很少值得担忧。你需要两个列表都非常大,否则你需要做大量的列表。一般来说,编写简洁的代码应该是您的主要目标,如果这是一个真正的问题,您应该只特别关注性能。还有一个问题,在这种情况下,如果我需要删除面板,因为我必须生成一个新的面板,但具有其他属性,我看到正在使用Dispose(),但它不会删除对象本身,它只会重置,如果我尝试使用Remove(),显然它会要求我提供控件部分,是否可以更改它?从列表中可以看出是的,尽管在这种情况下它将始终是4,所以我认为没有问题。你好。@LARC,它真的不知道你在说什么。不管怎样,都不会进行重置,也不会进行删除操作。您可以从其父控件中删除该控件,也可以处置该控件,这意味着释放其资源。不管怎样,对象仍然存在。关键是删除不会处理,但处理会删除。除非要重用子控件,只需调用其
Dispose
方法,否则在父控件
集合上调用
Remove
,以后可以重新添加它们。
    For i As Integer = pb.Controls.Count - 1 To 0 Step -1
        If pb.Controls(i).Name Like "*_A" OrElse pb.Controls(i).Name Like "*_B" Then
            pb.Controls.Remove(pb.Controls(i))
        End If
    Next