VB.NET:不再需要时删除控件

VB.NET:不再需要时删除控件,vb.net,winforms,user-interface,Vb.net,Winforms,User Interface,有点新手,请容忍我 为了提供一些背景信息,我尝试在WinForms中制作一个简单的应用程序,如下所示:- 主窗体(窗口)将在任何时候包含2个面板;左侧框架用于菜单选项,右侧框架用作内容窗格 单击表单顶部的4个按钮之一后,将创建一个面板(左侧菜单)并将其置于前面 在菜单中单击菜单选项时,将创建另一个内容面板并将其置于最前面 它似乎在按预期工作。(虽然我觉得这有点像蛮力的方法…)但是,我突然想到,在菜单和内容窗格之间切换也意味着会创建多个面板的副本,并且只会被提出的下一个面板“隐藏” 如果我的想法是

有点新手,请容忍我

为了提供一些背景信息,我尝试在WinForms中制作一个简单的应用程序,如下所示:-

  • 主窗体(窗口)将在任何时候包含2个面板;左侧框架用于菜单选项,右侧框架用作内容窗格

  • 单击表单顶部的4个按钮之一后,将创建一个面板(左侧菜单)并将其置于前面

  • 在菜单中单击菜单选项时,将创建另一个内容面板并将其置于最前面

  • 它似乎在按预期工作。(虽然我觉得这有点像蛮力的方法…)但是,我突然想到,在菜单和内容窗格之间切换也意味着会创建多个面板的副本,并且只会被提出的下一个面板“隐藏”

    如果我的想法是正确的,那么理论上就意味着需要越来越多的内存来保存这些不需要的对象,这当然是不可取的

    问题:我的想法准确吗?如果是的话,有没有干净的方法来移除不需要的面板

    或者,如果有人能提示我一个干净的解决方案来实现概述的接口,我将不胜感激


    谢谢

    据我所知,您的表单最多会创建2个附加面板,对吗

    如果这是正确的,为什么不从一开始就创建面板并使其不可见,然后在单击右键后使其可见


    对我来说,这听起来更清晰

    这种方法没有什么错。是的,您确实希望清理右侧面板的旧内容。这通常是错误的,使用面板的控件。Clear()方法是非常严重的资源泄漏。您必须处理旧控件。因此,大致上:

    Private Sub DisplaySelection(uc As UserControl)
       Do While Panel2.Controls.Count > 0
          Panel2.Controls(0).Dispose()
       Loop
       Panel2.Controls.Add(uc)
    End Sub
    
    这可以任意扩展。例如,一个很好的方法是在面板中放置一个表单,这样可以很容易地设计UI。停靠左边的树视图,旁边的面板完全停靠。为每个表单添加节点,将每个节点的Tag属性设置为表单的名称(如“Form2”,等等)。添加AfterSelect事件处理程序:

    Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
        DisplaySelection(CStr(e.Node.Tag))
    End Sub
    
    DisplaySelection()方法现在需要根据名称动态创建表单对象,并将其嵌入到面板中。该代码可以如下所示:

    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
    

    如果您是通过代码创建面板,则可以在完成后轻松地
    处理它们。但是,如果你再次调用它,你就必须重新创建它。基本上,我有几个类定义了内容/菜单等。因此,为了创建一个面板,我使用例如,>Dim menu As LeftMenu=New LeftMenu()>menu.BringToFront(),所以每次单击按钮时,我都会创建一个对象的新实例。对吗?