一点新手,请耐心等待......
为了给出一些背景知识,我试图在WinForms中创建一个这样的简单应用程序: -
主窗体(窗口)在任何时候都包含2个面板;菜单选项的左侧框架和内容窗格的右侧框架。
点击表格顶部的4个按钮之一后,将创建一个面板(左侧菜单)并将其放在前面。
当在菜单中单击菜单选项时,将创建另一个内容面板并将其放在前面。
它似乎按预期工作。 (虽然我觉得它有点像暴力方法...)但是,我想到,切换菜单和内容窗格也意味着将创建几个面板副本并且只是“隐藏” “由下一个小组提出。
如果我的想法是正确的,那理论上就意味着需要越来越多的记忆来保存这些不需要的物体,这当然是不可取的。
问题:我的想法是否正确?如果是这样,有没有一种干净的方法来移除不需要的面板?
或者,如果有人能提示我实施概述界面的清洁解决方案,我将非常感激。
谢谢!
答案 0 :(得分: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
这可以任意扩展。例如,一个不错的黑客就是在面板中放置一个表单,这样可以轻松设计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
答案 1 :(得分:0)
据我了解您的问题,您的表格最多可以创建2个面板,对吧?
如果这是正确的,为什么不从头开始创建面板并使它们不可见,然后 - 点击右键后 - 让它们可见?
听起来对我来说更干净