Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB.NET
Okay this may seem like an easy question but I can't seem to actually get it to work, and wonder if anybody can help me, or point me in the right direction as I have searched for an answer already but have drawn up blanks.
 
What I have is a flow layout panel, as the main panel on my Form. The reason for a flow layout panel is so I can easily add other panels to it without specifying location points (actually putting my Java layout manager knowledge to good use).
 
These other panels that are added to the flow layout panel are added dynamically by the actual user with a button marked "Add Panel". The button name is called btnAddPanel. When these panels are added, a button is also included in this panel (btndeleteButton) which when the user clicks is suppose to delete the panel which the button resides on (the parent panel of the button).
 
The problem is I can't seem to get the delete button to work. I sometimes can get the last panel that has been added to be removed, but even this is sometimes hit and miss.
 
When the user clicks the delete button on one of the panels, the parent panel needs to be removed.
 
This is the code I have already and the commented out parts are some left over pieces of code I have tried but failed to work. I have tried a lot more times to get it to work, but every attempt I have failed.
 
Any suggestions? Thanks Smile | :)
 
Public Class Form1
 
    Dim btndeleteButton As Button
    Dim dynamicPanel As Panel
 
    Private Sub btnAddPanel_Click(sender As System.Object, e As System.EventArgs) Handles btnAddPanel.Click
 
        dynamicPanel = New Panel
        dynamicPanel.Size = New System.Drawing.Size(357, 100)
        dynamicPanel.BackColor = Color.LightBlue
 
        btndeleteButton = New Button
        btndeleteButton.Width = 100
        btndeleteButton.Text = "Delete"
        AddHandler btndeleteButton.Click, AddressOf btndeleteButton_Click
 

        dynamicPanel.Controls.Add(btndeleteButton)
 
        FlowLayoutPanel1.Controls.Add(dynamicPanel)
 
    End Sub
 
    Private Sub btndeleteButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
 
        'FlowLayoutPanel1().Controls.Remove(dynamicPanel)
        'btndeleteButton.Parent.Dispose()

    End Sub
 
  
End Class
Posted 30-Nov-12 16:13pm
Comments
Krunal R at 30-Nov-12 23:45pm
   
Whats happening over here ? I mean is it giving you an error or what ??
Sergey Alexandrovich Kryukov at 1-Dec-12 0:12am
   
That's not exactly an exception; OP actually explained it, albeit not so accurately.
I explained how to resolve the problem -- please see my solution.
--SA

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

The code is just dirty, due to sharing of the instance field Form1.dynamicPanel. Very dirty. Just look carefully.
 
When the panel and deleting button is just one, everything is good, but if you try adding and removing panels in butterfly manner, the effect of sharing this variable comes into play. You think that you delete the panel having the button you are clicking on, but in fact the other instance of a panel is used, the one which was last added in this line:
FlowLayoutPanel1.Controls.Add(dynamicPanel) ' bad!
 
Can you see the problem now?
 
So, to resolve the problem, you should avoid passing reference to the shared field; remove the field Form1.dynamicPanel at all. You need to pass data used by an event handle through the arguments of the event handler. Do something like this:
 
Add a back reference to a panel to the instance of deleting button, using its Tag property:
    ' Dim btndeleteButton As Button ' remove form class fields
    ' Dim dynamicPanel As Panel ' remove form class fields
 
    Private Sub btnAddPanel_Click(sender As System.Object, e As System.EventArgs) Handles btnAddPanel.Click
 
        Dim btndeleteButton As Button ' make former field a stack variable
        Dim dynamicPanel As Panel ' this one, too
 
        dynamicPanel = New Panel
        dynamicPanel.Size = New System.Drawing.Size(357, 100)
        dynamicPanel.BackColor = Color.LightBlue
 
        btndeleteButton = New Button
 
        btndeleteButton.Tag = dynamicPanel ' button will remember
                                           ' the panel to delete

        ' ... the rest of your code 
        ' ...

    End Sub
 
In the handler code, type-cast sender to Button. It will also be the instance of the button clicked; now, extract an instance of the Panel from the button: takes Button.Tag and type-cast it to Panel. Remove this instance of a panel.
 
Problem solved.
 
Another solution is this: do it all in the code of the handler; extract an instance of Button by type-casting sender. Take Button.Parent and type-cast this Control to Panel: you can be sure that before deleting, this Control is certainly the required Panel. Remove it.
 
It will work, too.
 
[EDIT]
 
One more note: never ever use names like btnAddPanel_Click, Form1 and other auto-generated names. Give everything some semantic names. This is why you are given the Visual Studio refactorization engine. No underscores or numerics ("Label1", "Label2" and the like). In addition to the problems of maintenance and readability, you are violating (good) Microsoft naming conventions. Yes, Microsoft auto-generated code violates them, too, so what? These names are not designed to be kept; you are supposed to rename them all, to make them semantically sensible.
 
—SA
  Permalink  
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Maciej Los 235
1 OriginalGriff 215
2 Manfred R. Bihy 190
3 CHill60 180
4 _Amy 155
0 OriginalGriff 7,395
1 Sergey Alexandrovich Kryukov 6,163
2 Maciej Los 3,754
3 Peter Leow 3,448
4 CHill60 2,702


Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 1 Dec 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100