Search code examples
vb.netcontrolspanel

Delete Panel within inside another panel


I have a Panel that, in turn, has 4 panels inside. The interior panels are named "XXXX | 1 | A", "XXXX | 1 | B", "XXXX | 1 | C" and "XXXX | 1 | D", as you can see to differentiate them in the last character it has a letter.

In this case, what I want to do is always delete only the panels that are identified as A and B.

This is my code.

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

As you can see, with the variable controls_number I know that there are 4 Panels inside, but when going through the arrangement, it only reads 3 and only removes the Panel that is identified as B and does not reach Panel A.

Can you explain to me why you don't read the 4 Panels? Any ideas for me to go through all 4?

Thank you.


Solution

  • Don't EVER modify a list while enumerating it with a For Each loop. The simple solution in this and many other cases is to extract the items you want into a separate list and loop through that while removing the items from the original list. The removal will thus have no effect on the list that you're enumerating. In your case, that might look like this:

    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
    

    Calliing Dispose will remove the control from its parent and properly dispose it. If you just call Remove then the control is not disposed. Unless you intend to reuse the control, that's bad.