C# Form1与Form2窗体间频繁切换的处理

引言

窗体间切换对于处理一些参数设置等场合会时不时的遇到。偶尔的切换,不妨通过实例化的方式进行处理:

由Form1切换到Form2

Form2 frm2 = new Form2();

this.Hide();

frm2.Show();

由Form2切换到Form1

Form1 frm1 = new Form1();

this.Hide();

frm1.Show();

问题

如果频繁切换而每次都new进行实例化,产生的内存垃圾不好处理,dispose了好像也不太行,也不知道Anders Hejsberg开发C#时如何智能处理这些垃圾。别纠结了,自己想办法吧,无非就是首次new一下,以后就用现成的实例,就不要new了。

在Form2里创建Form1的实例,用静态变量LoadID2记录创建次数,不是首次就不要new了。加上这个静态变量也是无奈,开始时用if (frm1 == null)感觉应该行,但实际上每次Show后它就new,上了静态变量后通过对它的监测显示只是首次才new,于是就把它发布成了这篇博文。

- 方法 1

        public static Form1 frm1 = null;
        public static int LoadID2=0;
        private void Form2_Load(object sender, EventArgs e)
        {
            //if (frm1 == null)
            if (LoadID2 <= 0)
            {
                frm1 = new Form1();
                LoadID2 ++;
            }
        }

在Form1里创建Form2的实例

        public static Form2 frm2 = null;
        public static int LoadID1=0;
        private void Form1_Load(object sender, EventArgs e)
        {
            TextBox1.Text = "Initial TextLoad";
            TextBox2.Text = LoadID1.ToString();
            //if (frm2 == null)
            if (LoadID1<=0)
            {
                frm2 = new Form2();
                LoadID1++;
            }
        }

在Form1里加上Button1

        private void Button1_Click(object sender, EventArgs e)
        {
            this.Hide();
            //TextBox1.Text = LoadID1.ToString();   //如果在Form1上加TextBox1可以显示静态变量的值
            frm2.Show();
        }

在Form2里加上Button1

        private void Button1_Click(object sender, EventArgs e)
        {
            this.Hide();
            frm1.Show();
        }

主程序是以Form1为主窗体的,显示监测也在Form1的Button1中实现。

 

- 方法 2

主窗体 Form1

        public Form2 frm2 = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            frm2 = new Form2();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            this.Hide();
            frm2.Show();
        }

子窗体 Form2

        public Form1 frm1 = null;
        private void Form2_Load(object sender, EventArgs e)
        {
            frm1 = new Form1();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            this.Hide();
            foreach (Form ff in Application.OpenForms)
            {
                if (ff is Form2)                                //发现Form2窗体在就Hide了随之Show窗体Form1
                {
                    ff.Hide();
                    frm1.Show();
                    return;
                }
            }
        }

        private void Form2_FormClosed(object sender, FormClosedEventArgs e)
        {
            frm1.Show();
        }

窗体的隐藏可以用 Visible 属性true或false实现,但关闭Form2后属性不起作用的。就Show吧,Show则会自动装入的。

- 方法 3

与其窗体来回切换,还不如主窗体不HIDE,只让子窗体ShowDialog,一切都简单化了。

主窗体Form1上放个Button1,写上如下代码:

        public static Form2 frm2 = null;
        private void Button1_Click(object sender, EventArgs e)
        {
            if (frm2==null)
            {
                frm2 = new Form2();
            }
            frm2.FromForm1("This string comes from Form1");
            frm2.ShowDialog();
        }

子窗体Form2上放TextBox1和TextBox2和Button1

        public static string Frm1String = "";
        public void FromForm1(string instring)
        {
            Frm1String = instring;
            TextBox1.Text = Frm1String;
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            TextBox2.Text = "This string sets by Form2";
            this.Hide();
        }

主窗体ShowDialog子窗体时调用子窗体的方法时,先在子窗体的TextBox1上送显This string comes from Form1,然后显示子窗体。子窗体点Button1退出时在TextBox2上显示字符串This string sets by Form2。如此操作Form2, Form1和Form2上的内容均保持完好,Form2的静态变量FrmString可处理Form1送来的数据或任务指示等。窗体问题就不纠结了,继续学习,CSDN上要学的东西的太多了,2021排队等着我学呢。

- 方法 4

别在IDE创建Form2窗体了,用代码直接在Form1的命名空间里实现myForm2,添加按钮。

    public class myForm2 : Form //登录对话框类声明
    {
        public Button Button1;
        public myForm2()//构造函数
        {
            Button1 = new Button();
            Button1.Click += new EventHandler(Button1Click);
            this.Controls.Add(Button1);

            this.Button1.Size = new Size(130, 30);
            this.Button1.Location = new Point(100, 80);
        }

        void Button1Click(object sender, EventArgs e)

        {
             this.Hide();
            //this.Controls.Remove(Button1);
            //this.Button1.Dispose();
            //this.Close();
        }
    }

先定义 public myForm2 mfrm = null;
然后在Form1装载时实例化myForm2
mfrm = new myForm2();

然后在Form1的Button1里
mfrm.ShowDialog();

myForm2不用时注销它们
this.Controls.Remove(Button1);
this.Button1.Dispose();
this.Close();

代码多了些,但用起来更顺手,都在一个命名空间中完成。


 

心得

VS2019有个诊断会话,进程内存随两个窗体的Hide或Show的频繁切换而增加一点,既然想了办法又没有每次new那就认为C#会自动处理它。其实切换几次Form与现在64位系统下内存随便都是8GB以上相比,增加的内存并不很多。加之,写的程序也不是成年累月地连续性运行。但完美而又纠结的思想作祟,总想着程序吃内存会崩溃,程序越精练越好,其实真没必要,买个手机的钱可以买台超高级的台式机,计算机技术升级了,也真该升级思想意识了。

猜你喜欢

转载自blog.csdn.net/weixin_45707491/article/details/112267548