繁体   English   中英

c#如何在表单之间交换

[英]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实例时,您可以订阅新FormFormClosed事件并从处理程序显示您的初始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");
}

改变数字,显然

子表格

现在在您的项目中创建三个新表单。 将类命名为SubForm1SubForm2SubForm3

注意,我创建了三个子表单,而不是 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方法进行一些小的更改。 这些变化:

  1. 创建管理器
  2. 实例化主窗体以及三个子窗体。
  3. 并调用正常的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM