我正在使用Visual Studio 2010在VB.net中编写Windows窗体应用程序(仍然欢迎使用C#响应)。
我已经创建了应用程序的功能,现在正在处理UI流程。基本上,我需要使应用程序的所有功能从一开始就显示/消失,介绍形式。他们点击Introduction.vb表单中的一个选项,原始材料消失,并被他们点击的任何内容替换。然后,如果他们想要返回上一页,则在下一页上有一个后退按钮。 这是最初的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
正如您所看到的,现在我只是为应用程序的每个区域创建了一个单独的表单,并在开始时将它们从主表单链接起来。每个后续表单上的后退按钮只关闭窗口。这一切都很有效,除了新页面在新窗口中打开,我想避免。相反,我希望在原始窗口中打开新部件。
从我的研究中,我发现为了实现这一点,我需要将我创建的每个表单(我愚蠢地为每个表单创建一个表单)更改为UserControl对象,然后显示或隐藏适当地控制主要形式。问题是,我不确定如何做到这一点。我知道如何将我的Forms对象更改为UserControls对象,并修复与此相关的错误。
当我尝试开发逻辑以显示/隐藏主要介绍页面的UserControls时,我的问题就出现了。我在网上找到了结果,建议我创建一个包含所有控件的Dictionary,然后根据需要添加/删除它。我还发现结果表明我应该能够使用主页上按钮上的逻辑显示/隐藏表单。我无法使用这些方法中的任何一种,经常会遇到错误,指出&#34;顶级控件无法添加到控件中。&#34; 基本上,我卡住,困惑,我尝试似乎总是抛出错误,我想知道实现这一点的最佳方法是什么。
让我发帖(其中之一)我尝试过的确实有效:
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当然是替换旧的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
这个方法似乎草率,虽然我至少能够让下一个表单显示这种方式而不会抛出错误。例如,下一页上的后退按钮基本上只是清除所有旧控件,然后再次添加Introduction.vb UserControl,并再次显示它。那么,现在变量冲突呢?我将不得不确保我的所有变量名称都不同(如果我错了,请纠正我),因此对于每个表单,我将不得不将BackButton更改为BackButton1,BackButton2等。此方法似乎就像它将花费更多的时间而不是它的价值,而且阅读时会更加困惑。
我真的很感激,如果有人花时间解释一个更好的方法来做到这一点,这不是草率和易于维护,避免可变冲突,不是硬意大利面条编码在一起等。任何在线资源的链接我也会受到赞赏,但令人惊讶的是,我找不到很多超出我所说的内容。
答案 0 :(得分:3)
有数百种方法可以做到这一点,一种是将表单的属性TopLevel设置为false。或者您的MainForm应该包含一个面板,您可以动态加载UserControl。
基本上你正在寻找的是一个名为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;
}
答案 1 :(得分:1)
这是一个很好的例子。这假设您的表单上有一个名为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()
您需要将以前的表单放入一个集合中,这样您就可以通过从集合中提取最后一个项目来向后退。希望这会有所帮助。
答案 2 :(得分:1)
就个人而言,由于以下几个原因,我不是修改Controls
集合的粉丝:
ControlsCollection.Add
并查看)Here's a super bare-bones example of what I think you're asking for.
它使用TabPage
(没有标题)来托管控件(我添加了指示&#34;页面&#34的标签;但这些可以很容易地成为您的用户控件)。后退按钮由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;
}
}
请注意,这是一个非常简单的实现,不用担心问题的分离。如果您想让我了解更多细节,请告诉我,我很乐意详细说明。