引言
窗体间切换对于处理一些参数设置等场合会时不时的遇到。偶尔的切换,不妨通过实例化的方式进行处理:
由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以上相比,增加的内存并不很多。加之,写的程序也不是成年累月地连续性运行。但完美而又纠结的思想作祟,总想着程序吃内存会崩溃,程序越精练越好,其实真没必要,买个手机的钱可以买台超高级的台式机,计算机技术升级了,也真该升级思想意识了。