user3156487
user3156487

Reputation: 11

VB.NET : Deleting controls when no longer needed

Bit of a newbie, please bear with me...

To give some background, I'm trying to make in WinForms a simple app that goes like this :-

  1. The main Form (window) will, at any one time, contain 2 panels; a left-hand frame for menu options, and a right-hand frame as a content pane.

  2. Upon clicking one of 4 buttons on top of the Form, a Panel (left-hand menu) will be created and brought to the front.

  3. When a menu option is clicked in the menu, another Panel for the content will be created and brought to the front.

It seems to be working as intended. (although I kind of feel like its a bit of a brute force method...) But, it occurred to me that, switching through the menus and content panes would also mean that several duplicates of the Panels would be created and only "hidden" by the next Panel that is brought forward.

If my thinking is correct, then it would theoretically mean that more and more memory would be needed to hold these unwanted objects, which is of course not desirable.

Question : Is what I'm thinking accurate? And if so, is there a clean way to remove the unneeded panels?

Or, if anyone can hint me as to a clean solution to implementing the outlined interface, I would be much obliged.

Thanks!

Upvotes: 0

Views: 223

Answers (2)

Hans Passant
Hans Passant

Reputation: 942227

There's nothing wrong with this approach. And yes, you do want to clean up the old content of the right panel. That's often done incorrectly, using the panel's Controls.Clear() method is a very nasty resource leak. You have to dispose the old controls. So, roughly:

Private Sub DisplaySelection(uc As UserControl)
   Do While Panel2.Controls.Count > 0
      Panel2.Controls(0).Dispose()
   Loop
   Panel2.Controls.Add(uc)
End Sub

This can be arbitrarily extended. A nice hack for example is to put a form inside the panel, makes it easy to design your UI. Dock a TreeView on the left, a panel next to it that's fully docked. Add nodes for every form, set the Tag property of each node to the name of the form (Like "Form2", etc). Add the AfterSelect event handler:

Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
    DisplaySelection(CStr(e.Node.Tag))
End Sub

The DisplaySelection() method now needs to dynamically create the Form object from the name and embed it in the panel. That code can look like this:

Private Sub DisplaySelection(formName As String)
    If String.IsNullOrEmpty(formName) Then
        Throw New InvalidOperationException("You forgot to set the Tag property")
    End If
    '' Ignore if that form is already displayed
    If Panel1.Controls.Count > 0 AndAlso Panel1.Controls(0).GetType().Name = formName Then Return
    '' Destroy the currently displayed form, if any
    Do While Panel1.Controls.Count > 0
        Panel1.Controls(0).Dispose()
    Loop
    '' Generate full type name if necessary to get, say, "WindowsApplication.Form2"
    If Not formName.Contains(".") Then formName = Me.GetType().Namespace + "." + formName
    Dim frm = CType(System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(formName), Form)
    If frm Is Nothing Then Throw New InvalidOperationException("Cannot find form " + formName)
    '' Embed the form in the panel as a child control
    frm.TopLevel = False
    frm.FormBorderStyle = FormBorderStyle.None
    frm.Visible = True
    frm.Dock = DockStyle.Fill
    Panel1.Controls.Add(frm)
End Sub

Upvotes: 1

greece57
greece57

Reputation: 431

As I understand your question, your Form will create at max 2 additional panels, right?

If that is right, why not just create that panels from beginning and make them invisible, and then - after clicking the right button - make them visible?

That sounds to me more clean

Upvotes: 0

Related Questions