WinForm编程设置窗口最小化触发System.StackOverflowException问题
问题根本原因
- 你在窗体构造函数中直接修改
WindowState为最小化状态,此时窗体还未完成初始化和首次渲染,状态变更会触发异常的连锁事件调用。 frmMain_Resize事件处理方法中的操作(Hide()、修改ShowInTaskbar属性)本身会再次触发Resize事件,导致方法无限递归调用,最终抛出*System.StackOverflowException*。
修复方案
第一步:添加递归防护标记
在窗体类中添加私有字段,避免Resize事件重复触发执行:
private bool _isResizing = false;
第二步:改造Resize事件处理逻辑
添加逻辑锁,阻止递归调用:
private void frmMain_Resize(object sender, EventArgs e) { if (_isResizing) return; _isResizing = true; try { if (FormWindowState.Minimized == this.WindowState) { notifyIcon1.Visible = true; notifyIcon1.ShowBalloonTip(500); this.ShowInTaskbar = false; this.Hide(); } else if (FormWindowState.Normal == this.WindowState) { notifyIcon1.Visible = false; this.ShowInTaskbar = true; } } finally { _isResizing = false; } }
第三步:调整启动最小化的执行时机
不要在构造函数中设置窗口状态,改为在窗体首次渲染完成的Shown事件中执行最小化逻辑:
- 先删除构造函数里的
this.WindowState = FormWindowState.Minimized;代码 - 给窗体添加
Shown事件处理方法:
private void Form1_Shown(object sender, EventArgs e) { this.WindowState = FormWindowState.Minimized; }
如果想要避免启动时窗体闪一下,可以在构造函数中添加初始配置:
public Form1() { InitializeComponent(); this.Resize += new System.EventHandler(this.frmMain_Resize); // 初始隐藏任务栏图标,避免启动闪烁 this.ShowInTaskbar = false; getSettings(); startServer(); }
以上修改完成后,启动自动最小化到托盘的逻辑即可正常运行,原有手动点击最小化、托盘图标唤出窗口的功能也不会受影响。
内容的提问来源于stack exchange,提问作者Mumbira
相关产品推荐
相关产品推荐

