您的位置:首页 > 编程语言 > C#

[C#]窗体切换--避免开启多个线程

2015-06-06 23:11 561 查看
先说说这个多窗体的界面的解决的办法:

用到的方法很简单,就是程序运行就建立一个MainForm,在这个MainForm中设立一个Panel,同时设立几个按钮,按下每个按钮都在这个Panel中载入不同的窗体,这样就解决了多窗体的切换。



提示:

在Panel的子窗体可以通过设置Form的FormBorderStyle为none,去掉它的最大化最小化和关闭按钮。但是一旦设置这个属性就必须手动的调用这个窗体的close方法来关闭这个窗体,因为调用这个方法和鼠标点击窗体的x按钮是一样的效果,都会调用窗体的close函数。同时这个函数的调用也会触发窗体的formclosing等事件。

下面看一下第一次写的代码:

//MainForm的代码
public class RobotArrounding : Form
{
private int curSelect = 0;

public RobotArrounding()
{
InitializeComponent();

this.pnlMain.Controls.Clear();
MonitorForm monitorFrm = new MonitorForm();

monitorFrm.TopLevel = false;
monitorFrm.Dock = DockStyle.Fill;
monitorFrm.Show();

this.pnlMain.Controls.Add(monitorFrm);

}

private void btnMonitor_Click(object sender, EventArgs e)
{
if (curSelect != 0)
{
this.pnlMain.Controls.Clear();
MonitorForm monitorFrm = new MonitorForm();

monitorFrm.TopLevel = false;
monitorFrm.Dock = DockStyle.Fill;
monitorFrm.Show();

this.pnlMain.Controls.Add(monitorFrm);
}

curSelect = 0;

}

private void btnPlane_Click(object sender, EventArgs e)
{
if (curSelect != 1)
{
this.pnlMain.Controls.Clear();

CheckingPlane planeFrm = new CheckingPlane();

planeFrm.TopLevel = false;
planeFrm.Dock = DockStyle.Fill;
planeFrm.Show();

this.pnlMain.Controls.Add(planeFrm);
}
curSelect = 1;
}

private void btnHistoryChecking_Click(object sender, EventArgs e)
{
if (curSelect != 2)
{
this.pnlMain.Controls.Clear();
HistoryChecking historyFrm = new HistoryChecking();

historyFrm.TopLevel = false;
historyFrm.Dock = DockStyle.Fill;
historyFrm.Show();

this.pnlMain.Controls.Add(historyFrm);
}
curSelect = 2;
}

private void bntExit_Click(object sender, EventArgs e)
{
this.Close();
//退出整个程序
Application.Exit();
}
}


  代码很简单,每次点击按钮都new一个新的窗体并显示。但是后来发现这样有问题,那就是多次按按钮,切换界面以后,原本new出来的窗体并没有销毁,没有被垃圾回收器收回。而是在整个程序退出的时候才调用了窗体的close方法,验证的方法就是在每一个窗体中增加formclosing事件,验证这个事件触发的时间,代码:

//其中的一个界面的类
public partial class CheckingPlane : Form
{
public CheckingPlane()
{
InitializeComponent();
}

private void CheckingPlane_FormClosing(object sender, FormClosingEventArgs e)
{
int a = 0;
a = 10;
}
}


  在MainForm调用application.Exit()方法得时候,发现这个窗体类的FormClosing事件执行了好多次,这个原因就是切换好多次的窗体之后,new出来了好多的窗体的实例。

解决的办法:

如果一个窗体没有被要求显示,那么这个窗体就不用new一个实例,如果这个窗体要求显示,那么就new一个窗体的实例,然后一直保持一个窗体的单例模式,直到整个程序退出时才销毁这个窗体。

public partial class RobotArrounding : Form
{
private int curSelect = 0;
private Form[] selectFrm = null;

public RobotArrounding()
{
InitializeComponent();
selectFrm = new Form[3];

this.pnlMain.Controls.Clear();

selectFrm[0] = new MonitorForm();

selectFrm[0].TopLevel = false;
selectFrm[0].Dock = DockStyle.Fill;
selectFrm[0].Show();

this.pnlMain.Controls.Add(selectFrm[0]);

}

private void btnMonitor_Click(object sender, EventArgs e)
{
if (curSelect != 0)
{
this.pnlMain.Controls.Clear();
if (selectFrm[0] == null || selectFrm[0].IsDisposed)
{
selectFrm[0] = new MonitorForm();

selectFrm[0].TopLevel = false;
selectFrm[0].Dock = DockStyle.Fill;

}
else
{
selectFrm[0].Activate();
}

selectFrm[curSelect].Hide();
selectFrm[0].Show();

this.pnlMain.Controls.Add(selectFrm[0]);
}
curSelect = 0;

}

private void btnPlane_Click(object sender, EventArgs e)
{
if (curSelect != 1)
{
this.pnlMain.Controls.Clear();

if (selectFrm[1] == null || selectFrm[1].IsDisposed)
{
selectFrm[1] = new CheckingPlane();

selectFrm[1].TopLevel = false;
selectFrm[1].Dock = DockStyle.Fill;
}
else
{
selectFrm[1].Activate();
}

selectFrm[curSelect].Hide();
selectFrm[1].Show();

this.pnlMain.Controls.Add(selectFrm[1]);
}
curSelect = 1;
}

private void btnHistoryChecking_Click(object sender, EventArgs e)
{
if (curSelect != 2)
{
this.pnlMain.Controls.Clear();

if (selectFrm[2] == null || selectFrm[2].IsDisposed)
{
selectFrm[2] = new HistoryChecking();

selectFrm[2].TopLevel = false;
selectFrm[2].Dock = DockStyle.Fill;
}
else
{
selectFrm[2].Activate();
}

selectFrm[curSelect].Hide();
selectFrm[2].Show();

this.pnlMain.Controls.Add(selectFrm[2]);
}
curSelect = 2;
}

private void bntExit_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++ )
{
if (selectFrm[i] != null)
{
selectFrm[i].Close();
}
}

this.Close();

Application.Exit();
}

}


  这样写还有一个小的问题,那就是我自己的继承自Form的窗体类,如果有自己定义的函数,利用多态访问这个窗体的时候就不能访问到这个函数。其实这个也很简单,在需要访问子类自定义的函数的时候,强制转换一下类型就可以了。

这样一来,不管你切换多少次窗体,都只有一个窗体的实例了,这样就能防止new很多的窗体实例了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: