我正在使用Visual Studio 2010在VB.net中编写Windows窗体应用程序(C#响应仍然受欢迎)。
我已经创build了我的应用程序的function,现在正在处理UIstream程。 基本上,我需要使应用程序的所有function从一开始就出现/消失,介绍性的forms。 他们点击Introduction.vb表单中的一个选项,原始材质消失,并被点击的任何东西取代。 然后,如果他们想要返回到前一页,则在下一页上有一个后退button。 这里是原来的Introduction.vb:
Public Class Introduction Inherits System.Windows.Forms.Form Private Sub Introduction_Load(sender As System.Object, e As System.EventArgs) Handles Me.Load End Sub Private Sub AddOrRemoveButton_Click(sender As System.Object, e As System.EventArgs) Handles AddOrRemoveButton.Click AddRemoveCompany.Show() '<-- Show the AddRemoveCompany.vb form when they click on the button. End Sub Private Sub InvoiceDocumentButton_Click(sender As System.Object, e As System.EventArgs) Handles InvoiceDocumentButton.Click InvoicePrinterAndDocCreator.Show() '<-- .vb form End Sub Private Sub LockOrUnlockButton_Click(sender As System.Object, e As System.EventArgs) Handles LockOrUnlockButton.Click LockUnlockPIN.Show() '<-- .vb form End Sub Private Sub ToExcelButton_Click(sender As System.Object, e As System.EventArgs) Handles ToExcelButton.Click ToExcel.Show() '<-- .vb form End Sub End Class
正如您所看到的,现在我只是简单地为应用程序的每个区域创build了一个单独的表单,并在开始时将它们从主表单链接起来。 每个后续表单上的后退button只需closures窗口即可。 这一切都很好,除了新的页面打开了新的窗口,我想避免。 相反,我想要在原始窗口中打开新的零件。
从我的研究中,我发现为了实现这个,我需要将每个我创build的表单(我愚蠢地为每个表单创build一个表单)更改为UserControl对象,然后适当地显示或隐藏控件closures的主要forms。 问题是,我不确定如何做到这一点。 我知道如何将我的Forms对象更改为UserControls对象,并修复与此相关的错误。
我的问题来了,当我尝试开发显示/隐藏UserControls的主要,介绍页面的逻辑。 我在网上find了结果,build议我创build一个包含我所有控件的字典,然后根据需要添加/删除它。 我还发现了一些结果,我应该简单地使用主页面上button上的逻辑显示/隐藏表单。 我不能让这两种方法中的任何一种工作,经常遇到一个错误,说明“顶级控制不能添加到控件”。 基本上,我卡住了,困惑,我尝试似乎总是抛出错误,我想知道什么是最好的方式来实现这一点。
让我发表(其中之一)我曾经尝试过的实际工作:
Public Class MainForm Private Sub MainForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load Dim x = New Introduction Me.Controls.Add(x) x.Show() End Sub End Class
这个MainForm当然会replace旧的Introduction.vb表单,而不是直接在蝙蝠上显示Introduction.vb UserControl。 这里是新的Introduction.vb UserControl:
Public Class Introduction Inherits System.Windows.Forms.UserControl Private Sub Introduction_Load(sender As System.Object, e As System.EventArgs) Handles Me.Load End Sub Private Sub AddOrRemoveButton_Click(sender As System.Object, e As System.EventArgs) Handles AddOrRemoveButton.Click ' Testing logic here: Dim y = New AddRemoveCompany '<-- One of my old forms that was converted to a UserControl. MainForm.Controls.Clear() MainForm.Controls.Add(y) y.Show() End Sub Private Sub InvoiceDocumentButton_Click(sender As System.Object, e As System.EventArgs) Handles InvoiceDocumentButton.Click InvoicePrinterAndDocCreator.Show() '<-- Still works, but still opens in a new window End Sub Private Sub LockOrUnlockButton_Click(sender As System.Object, e As System.EventArgs) Handles LockOrUnlockButton.Click LockUnlockPIN.Show() End Sub Private Sub TRSToExcelButton_Click(sender As System.Object, e As System.EventArgs) Handles TRSToExcelButton.Click TRSToExcel.Show() End Sub End Class
这种方法似乎马虎,虽然我至less能够得到下一个表单显示这种方式,而不会引发错误。 例如,下一页的后退button基本上只是清除所有旧的控件,然后再次添加在Introduction.vb UserControl中,并再次显示。 另外,现在variables冲突呢? 我将不得不确保所有的variables名称是不同的(纠正我,如果我错了),所以对于每个forms,我将不得不将BackButton更改为BackButton1,BackButton2,等等。比它值得更多的时间,更难以通读。
我真的很感激,如果有人花时间来解释一个更好的方式来做到这一点,这是不马虎,很容易维护,避免可变的冲突,不是硬面条编码在一起,等等任何在线资源的链接将不胜感激同样,我惊奇地发现我所谈论的内容并不多。
有几百种方法可以做到这一点,其一是将表单的属性TopLevel设置为false。 或者你的MainForm应该包含一个面板,你可以动态加载UserControls。
基本上你正在寻找的是一个叫做Composite UI的概念。 在.NET中最复合的UI应用程序使用WPF,因为更适合(imho)。 但是对于WinForms也有相当简单的概念(正如我前面提到的,创建一个面板并动态加载UserControls)。
我必须承认,我没有读通过所有的文本(因为它是一个很简单的问题,很多信息的方式)。 所以我希望我的一切都正确。
例如:
public void button_Click(object sender, EventArgs e) { this.panelBoarder.Controls.Clear() //Hide old content if (this.pageTwo == null) this.pageTwo = new PageTwo(); // Create Page Two this.panelBoarder.Controls.Add(this.pageTwo); this.pageTwo.Visible = true; }
这是一个很好的例子。 这假设你的表单上有一个名为Panel1的面板,而你想在该面板上显示的表单是Form2:
Dim f2 As New Form2 f2.TopLevel = False f2.ControlBox = False f2.FormBorderStyle = Windows.Forms.FormBorderStyle.None Panel1.Controls.Add(f2) f2.Show()
你会想把你以前的表单放到一个集合中,这样你就可以总是从集合中拉出最后一个东西。 希望这可以帮助。
就个人而言,我不是修改Controls
集合的粉丝,原因有两个:
ControlsCollection.Add
和看看) 这是我想你要求的一个超级简单的例子。
它使用TabPage
的(没有头)来托管控件(我添加了标签,指示“页面”,但这些可以很容易地成为您的用户控件)。 后退按钮由Stack
处理,因为这是您要查找的内容 – 推送新的页面选择,并在用户想要返回时弹出它们:
public partial class Form1 : Form { //... Stack<TabPage> breadCrumbs = new Stack<TabPage>(); private void SwitchTabs(TabPage page) { breadCrumbs.Push(tabControl1.SelectedTab); tabControl1.SelectedTab = page; } //... //Go back private void toolStripButton1_Click(object sender, EventArgs e) { if(breadCrumbs.Count == 0) return; var lastTab = breadCrumbs.Pop(); tabControl1.SelectedTab = lastTab; } }
请注意,这是一个非常简单的实现,不用担心分离问题。 让我知道如果你想让我更详细的,我会很乐意详细说明。