前两天,在做一个小软件时碰到一个怪异的StackOverflowException异常,试了几次后还是百思不得其解。
当时我想做的功能很简单:我想在程序开始启动时和在窗口被最小化后,自动隐藏掉窗口。
场景重现:
打开VS2010或VS2008,建立一个新的应用程序项目,VS会自动帮我们建立一个Form1窗口文件,回到代码编辑窗口,会看到如下的代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
{
public Form1()
{
InitializeComponent();
}
}
好,现在加上我们需要的代码实现在窗体最小化时自动隐藏掉窗体:
代码
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
F5运行,程序正常,可达到我们想要的效果。。OK,现在问题来了:因为我还需要在程序一启动时也自动隐藏掉。所以我就写了以下这句代码:
代码
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
//自动将窗口最小化, 以便在事件中自动处理隐藏
this.WindowState = FormWindowState.Minimized;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
//自动将窗口最小化, 以便在事件中自动处理隐藏
this.WindowState = FormWindowState.Minimized;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
即加了上面代码中红色的那句代码,代码看起来是正常的,可是F5运行,VS却提示我这样的错误:
怪事了,怎么出现堆栈溢出了呢?!难道那个Form1_SizeChanged函数出现递归调用了?调试运行,却发现根本没有递归调用。那问题出现在哪里呢?
经N次的测试检查,发现导致出现这个异常的语句是“this.ShowInTaskbar = false;”,有点怪异!!将这条语句删除或注释后,程序运行良好,但是窗体却在任务栏里出现了。如果单单这样,那问题还好解决,但更怪异的事情却来了,因为我调试时顺手写了这样的代码:
代码
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
//不在任务栏里显示
this.ShowInTaskbar = false;
//自动将窗口最小化, 以便在事件中自动处理隐藏
this.WindowState = FormWindowState.Minimized;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
//不在任务栏里显示
this.ShowInTaskbar = false;
//自动将窗口最小化, 以便在事件中自动处理隐藏
this.WindowState = FormWindowState.Minimized;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
即增加了上面的红色语句,按F5运行,天!程序正常运行,异常没有发生?!!
这。。这究竟是怎么一回事?我也不懂了。。。望哪位兄弟能帮我解答一下?在此多谢先了!
注:
上面的异常解决方法还可以换一种方法,即在Load事件里处理,也是不会发生异常,如下代码:
代码
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
//窗口显示前自动最小化
this.WindowState = FormWindowState.Minimized;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
{
public Form1()
{
InitializeComponent();
//窗口有变化时进行窗体处理
this.SizeChanged += new EventHandler(Form1_SizeChanged);
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
//窗口显示前自动最小化
this.WindowState = FormWindowState.Minimized;
}
void Form1_SizeChanged(object sender, EventArgs e)
{
//窗体如果已被最小化,则隐藏窗体
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
this.ShowInTaskbar = false;
}
}
}
示例项目代码下载: