【问题标题】:VB.NET : Deleting controls when no longer neededVB.NET:不再需要时删除控件
【发布时间】:2014-02-20 22:03:20
【问题描述】:

新手,请多多包涵……

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

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

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

  3. 当在菜单中单击一个菜单选项时,将创建另一个用于内容的面板并将其置于最前面。

它似乎按预期工作。 (虽然我觉得它有点像蛮力方法......)但是,在我看来,切换菜单和内容窗格也意味着将创建多个面板副本,并且只会“隐藏” " 由提出的下一个小组提出。

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

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

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

谢谢!

【问题讨论】:

  • 如果您通过代码创建面板,您可以在完成后轻松Dispose 他们。但是,如果您再次调用它,则必须重新创建它

标签: vb.net winforms user-interface


【解决方案1】:

这种方法没有错。是的,您确实想清理右侧面板的旧内容。这通常是错误的,使用面板的 Controls.Clear() 方法是一个非常讨厌的资源泄漏。您必须处理旧控件。所以,大致:

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

这可以任意扩展。例如,一个不错的 hack 是将 form 放在面板中,这样可以轻松设计 UI。将 TreeView 停靠在左侧,旁边是一个完全停靠的面板。为每个表单添加节点,将每个节点的 Tag 属性设置为表单的名称(如“Form2”等)。添加 AfterSelect 事件处理程序:

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

DisplaySelection() 方法现在需要根据名称动态创建 Form 对象并将其嵌入到面板中。该代码可能如下所示:

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

【讨论】:

    【解决方案2】:

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

    如果那是正确的,为什么不从头开始创建面板并使其不可见,然后 - 在单击右侧按钮后 - 使其可见?

    听起来更干净

    【讨论】:

    • 基本上我有几个类来定义内容/菜单等。所以要创建一个面板,我使用例如 > Dim menu As LeftMenu = New LeftMenu() > menu.BringToFront() 所以每次单击按钮时,我都会创建对象的新实例。对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 2023-01-29
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多