删除另一个面板内的面板
Delete Panel within inside another panel
我有一个面板,里面有 4 个面板。内部面板被命名为“XXXX | 1 | A”、“XXXX | 1 | B”、“XXXX | 1 | C”和“XXXX | 1 | D”,您可以在最后一个字符中看到它们的区别一封信。
在这种情况下,我想做的是始终只删除标识为 A 和 B 的面板。
这是我的代码。
Dim clickedLabel = DirectCast(DirectCast(DirectCast(sender, ToolStripMenuItem).Owner, ContextMenuStrip).SourceControl, Panel)
pb = clickedLabel.Parent
Dim controls_number As Integer = pb.Controls.Count
Dim spliterb
Dim con As Control
For Each con In pb.Controls
spliterb = con.Name.Split("|")
If spliterb(2).ToString = ("A") Or spliterb(2).ToString = ("B") Then
pb.Controls.Remove(con)
End If
Next
如您所见,通过变量controls_number我知道里面有4个Panel,但是在进行排列时,它只读取了3个并且只删除了标识为B的Panel并且没有未到达面板 A.
你能解释一下为什么你不看这 4 个面板吗?我有什么想法可以完成所有 4 个步骤吗?
谢谢。
首先你不能用管道字符“|”重命名控件因为这是设计师不允许的。
但是在下面的示例中,我假设它是一个下划线字符“_”。
现在当你循环一个集合时,如果它在这个循环中改变了她的维度,你就会失去在新 length/dimension 之后的元素数量(你删除)。
因此,要做到这一点,您可以将逆循环(最大维度为 0)用作技巧,在这种情况下,其余元素始终在循环中 inside/present。
下面这段代码说明了我的意思。
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
永远不要在使用 For Each
循环枚举列表时修改它。在这种情况和许多其他情况下,简单的解决方案是将您想要的项目提取到一个单独的列表中,然后循环遍历该列表,同时从原始列表中删除这些项目。因此,删除不会对您正在枚举的列表产生任何影响。在您的情况下,可能看起来像这样:
Dim panels = pb.Controls.
OfType(Of Panel)().
Where(Function(pnl) pnl.Name.EndsWith("|A") OrElse
pnl.Name.EndsWith("|B")).
ToArray()
For Each pnl In panels
pnl.Dispose()
Next
调用 Dispose
将从其父控件中删除控件并正确处置它。如果您只是调用 Remove
则控件不会被释放。除非您打算重用该控件,否则很糟糕。
我有一个面板,里面有 4 个面板。内部面板被命名为“XXXX | 1 | A”、“XXXX | 1 | B”、“XXXX | 1 | C”和“XXXX | 1 | D”,您可以在最后一个字符中看到它们的区别一封信。
在这种情况下,我想做的是始终只删除标识为 A 和 B 的面板。
这是我的代码。
Dim clickedLabel = DirectCast(DirectCast(DirectCast(sender, ToolStripMenuItem).Owner, ContextMenuStrip).SourceControl, Panel)
pb = clickedLabel.Parent
Dim controls_number As Integer = pb.Controls.Count
Dim spliterb
Dim con As Control
For Each con In pb.Controls
spliterb = con.Name.Split("|")
If spliterb(2).ToString = ("A") Or spliterb(2).ToString = ("B") Then
pb.Controls.Remove(con)
End If
Next
如您所见,通过变量controls_number我知道里面有4个Panel,但是在进行排列时,它只读取了3个并且只删除了标识为B的Panel并且没有未到达面板 A.
你能解释一下为什么你不看这 4 个面板吗?我有什么想法可以完成所有 4 个步骤吗?
谢谢。
首先你不能用管道字符“|”重命名控件因为这是设计师不允许的。 但是在下面的示例中,我假设它是一个下划线字符“_”。 现在当你循环一个集合时,如果它在这个循环中改变了她的维度,你就会失去在新 length/dimension 之后的元素数量(你删除)。 因此,要做到这一点,您可以将逆循环(最大维度为 0)用作技巧,在这种情况下,其余元素始终在循环中 inside/present。
下面这段代码说明了我的意思。
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
永远不要在使用 For Each
循环枚举列表时修改它。在这种情况和许多其他情况下,简单的解决方案是将您想要的项目提取到一个单独的列表中,然后循环遍历该列表,同时从原始列表中删除这些项目。因此,删除不会对您正在枚举的列表产生任何影响。在您的情况下,可能看起来像这样:
Dim panels = pb.Controls.
OfType(Of Panel)().
Where(Function(pnl) pnl.Name.EndsWith("|A") OrElse
pnl.Name.EndsWith("|B")).
ToArray()
For Each pnl In panels
pnl.Dispose()
Next
调用 Dispose
将从其父控件中删除控件并正确处置它。如果您只是调用 Remove
则控件不会被释放。除非您打算重用该控件,否则很糟糕。