[英]c# How to swap between forms
我的应用程序需要隐藏初始表单并打开四个新表单中的任何一个。 我可以隐藏首字母并打开所选表单:
private void btn_Option1_Click(object sender, EventArgs e){
Visible = false;
Application x = new Application();
x.show();
}
我的问题是如何关闭第二个表单并重新打开原始表单? 或者我认为在每个表单打开时关闭每个表单是合理的,但这似乎很浪费。
听起来您需要FormClosed
事件。
当您从初始Form
创建新Form
实例时,您可以订阅新Form
的FormClosed
事件并从处理程序显示您的初始Form
。
这样,只要您的新Form
关闭,事件处理程序就会触发,您的初始Form
将再次可见。
// This is a method that you would add to your initial Form.
private void SubForm_Closed(object sender, FormClosedEventArgs e)
{
Visible = true;
}
private void btn_Option1_Click(object sender, EventArgs e)
{
Visible = false;
Application x = new Application();
x.FormClosed += SubForm_Closed;
x.show();
}
如果您使用 Hide(),表单“基本上”会消失,您甚至不会在任务栏中看到它。 然后,您可以通过从后续表单之一中显示它来打开。 我把下面的东西放在一起,只是快速测试了它,所以 YMMV,你需要清理它并让它为你工作,但它应该说明这一点。 创建 Windows 窗体应用程序。 将其称为“WindowsFormsApp2”,因为这是我使用的。 粘贴以下代码:
using System;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Form2 form2;
Form3 form3;
Form4 form4;
Form5 form5;
private void button1_Click_1(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
form2 = new Form2(this);
form2.Show();
}
if (checkBox2.Checked)
{
form3 = new Form3(this);
form3.Show();
}
if (checkBox3.Checked)
{
form4 = new Form4(this);
form4.Show();
}
if (checkBox4.Checked)
{
form5 = new Form5(this);
form5.Show();
}
this.Hide();
}
}
}
将以下代码粘贴到 Form1 设计器中:
namespace WindowsFormsApp2
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.checkBox3 = new System.Windows.Forms.CheckBox();
this.checkBox4 = new System.Windows.Forms.CheckBox();
this.button1 = new System.Windows.Forms.Button();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.checkBox4);
this.groupBox1.Controls.Add(this.checkBox3);
this.groupBox1.Controls.Add(this.checkBox2);
this.groupBox1.Controls.Add(this.checkBox1);
this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(274, 73);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Forms";
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(17, 32);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(55, 17);
this.checkBox1.TabIndex = 0;
this.checkBox1.Text = "Form2";
this.checkBox1.UseVisualStyleBackColor = true;
//
// checkBox2
//
this.checkBox2.AutoSize = true;
this.checkBox2.Location = new System.Drawing.Point(78, 32);
this.checkBox2.Name = "checkBox2";
this.checkBox2.Size = new System.Drawing.Size(55, 17);
this.checkBox2.TabIndex = 1;
this.checkBox2.Text = "Form3";
this.checkBox2.UseVisualStyleBackColor = true;
//
// checkBox3
//
this.checkBox3.AutoSize = true;
this.checkBox3.Location = new System.Drawing.Point(139, 32);
this.checkBox3.Name = "checkBox3";
this.checkBox3.Size = new System.Drawing.Size(55, 17);
this.checkBox3.TabIndex = 2;
this.checkBox3.Text = "Form4";
this.checkBox3.UseVisualStyleBackColor = true;
//
// checkBox4
//
this.checkBox4.AutoSize = true;
this.checkBox4.Location = new System.Drawing.Point(200, 32);
this.checkBox4.Name = "checkBox4";
this.checkBox4.Size = new System.Drawing.Size(55, 17);
this.checkBox4.TabIndex = 3;
this.checkBox4.Text = "Form5";
this.checkBox4.UseVisualStyleBackColor = true;
//
// button1
//
this.button1.Location = new System.Drawing.Point(12, 91);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(199, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Open Selected Forms";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click_1);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.button1);
this.Controls.Add(this.groupBox1);
this.Name = "Form1";
this.Text = "Form1";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.CheckBox checkBox4;
private System.Windows.Forms.CheckBox checkBox3;
private System.Windows.Forms.CheckBox checkBox2;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.Button button1;
}
}
添加 4 个 Windows 窗体:Form2、Form3、Form4 和 Form5。
将下面的代码粘贴到每一个,只需将每个上的表单名称更改为正确的名称(Form3、Form4、Form5):
using System;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form2 : Form
{
public Form2(Form1 Form1In)
{
InitializeComponent();
form1 = Form1In;
}
Form1 form1;
private void button1_Click(object sender, EventArgs e)
{
form1.Show();
}
}
}
最后将下面的代码粘贴到每个表单的设计器中,并将 Form2 以外的表单的名称更改为它们各自的名称:
namespace WindowsFormsApp2
{
partial class Form2
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(22, 21);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(104, 23);
this.button1.TabIndex = 0;
this.button1.Text = "Show Form1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.button1);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
}
}
然后运行它。
这是一个闪亮的新轮子。 它将所有逻辑集中在一个 Manager 类中。
一个子表单基类
首先,我们将为所有子表单创建一个基类。 这样,您就不需要将表单切换逻辑放入每个表单中。
在您的项目中创建一个新表单,将其命名为ShowHideFormBase
,更改为“查看代码”视图并更改样板文件,使其看起来像这样:
public partial class ShowHideFormBase : Form
{
public ShowHideFormManager Manager { get; private set; }
public ShowHideFormBase()
{
Manager = null;
InitializeComponent();
}
public void SetManager (ShowHideFormManager manager)
{
Manager = manager;
}
}
我们稍后会创建 Manager 类
我真的很想在ShowHideFormBase
上有一个构造函数, ShowHideFormBase
ShowHideFormManager
实例作为参数。 Windows 窗体设计器真的不喜欢具有非默认构造函数的窗体基类。 这就是人生。
在此窗体的设计器中,显示窗体的属性,然后更改为“事件”视图(闪电图标)。 双击FormClosing
事件。 这会将ShowHideWindowBase_FormClosing
处理程序的此代码添加到您的基类。 更改它,使其看起来像这样。
private void ShowHideWindowBase_FormClosing(object sender, FormClosingEventArgs e)
{
Debug.Assert(Manager != null); //Make sure that SetManager was called
e.Cancel = true;
Manager.HideAll();
}
e.Cancel=true;
说“我知道有人试图关闭这个表单,不要让它关闭” 。 相反,我们将隐藏所有子窗体,包括这个子窗体。
那堂课就完成了。 现在让我们做经理类。
管理者
在您的项目名称ShowHideFormManager
创建一个新类。 使用此代码:
public class ShowHideFormManager
{
private Dictionary<string, ShowHideFormBase> _forms = new Dictionary<string, ShowHideFormBase>();
private Form _mainForm;
public ShowHideFormManager(Form mainForm)
{
_mainForm = mainForm;
}
// This will add a sub form to be managed
public void Add(string windowsName, ShowHideFormBase form)
{
_forms.Add(windowsName, form);
}
// This will hide all managed sub forms and show the main form
public void HideAll()
{
_mainForm.Show();
foreach (var formPair in _forms)
{
formPair.Value.Hide();
}
}
// this will hide the main form and show the named sub form
public void Show(string formToShowName)
{
_mainForm.Hide();
foreach (var formPair in _forms)
{
if (formPair.Key != formToShowName)
{
formPair.Value.Hide();
}
}
if (_forms.TryGetValue(formToShowName, out var formToShow))
{
formToShow.Show();
}
}
}
请注意,闪亮的新轮子大约有 75 或 80 行代码。
申请的主表格
我假设您的应用程序中有一个名为Form1
的表单(在您创建应用程序时创建的表单)。
添加此私有字段:
private ShowHideFormManager _manager = null;
和这个公共方法:
public void SetManager(ShowHideFormManager manager)
{
_manager = manager;
}
在主窗体上放置三个按钮,将它们的Name
属性设置为“SubForm1Btn”、“SubForm2Btn”和“SubForm3Btn”,并将Text
属性设置为有用的东西。 在点击处理程序中,为每个按钮做这样的事情:
private void SubForm1Btn_Click(object sender, EventArgs e)
{
_manager.Show("Sub Form 1");
}
改变数字,显然
子表格
现在在您的项目中创建三个新表单。 将类命名为SubForm1
、 SubForm2
和SubForm3
。
注意,我创建了三个子表单,而不是 4 个——创建第四个会很容易
打开每个表单的代码视图。 我们将对这三种形式进行的唯一更改是将类声明和构造函数更改为:
public partial class SubForm1 : ShowHideFormBase
{
public SubForm1(ShowHideFormManager manager)
{
InitializeComponent();
SetManager(manager);
}
}
对于所有三种形式:1、2 和 3,显然
这将基类从Form
更改为ShowHideFormBase
。 它还使得这些表单中的每一个都必须使用ShowHideFormManager
实例进行初始化,并且我们调用SetManager
(这是一个基类方法)来使用管理器初始化表单。
最后,对 Program.cs 的更改
最后,我们将对 Program.cs 中的Main
方法进行一些小的更改。 这些变化:
Application.Run
方法这是新的Main
方法:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var mainForm = new Form1();
var manager = new ShowHideFormManager(mainForm);
mainForm.SetManager(manager);
var subForm1 = new SubForm1(manager);
var subForm2 = new SubForm2(manager);
var subForm3 = new SubForm3(manager);
manager.Add("Sub Form 1", subForm1);
manager.Add("Sub Form 2", subForm2);
manager.Add("Sub Form 3", subForm3);
Application.Run(mainForm);
}
重要提示:您在manager.Add
调用中使用的字符串(例如"Sub Form 1"
)必须与您在每次调用_manager.Show("Sub Form 1");
传递的字符串完全匹配_manager.Show("Sub Form 1");
在按钮处理程序中。 完成此操作后,我决定应该使用enum
,但一切正常。
这个怎么运作
按 F5 和主窗体(上面有三个按钮)应该弹出。 按任意一个按钮,相应的窗体将弹出(主窗体将隐藏)。 关闭子表单,主表单将重新打开,让您再次按下该按钮或另一个按钮。
当您查看此内容时,请注意主表单或子表单几乎没有更改。 神奇之处在于基类和管理器类的形式。 您可以对任何表单做任何您想做的事情(只要您在正确的位置进行了那些最小的更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.