NotifyIcon 初始化必须设置 Icon 属性且 Visible = true,最小化需监听 SizeChanged 事件隐藏窗体并显示图标,双击还原须同时调用 Show、Activate 和设 WindowState = Normal,关闭时务必 Visible = false 并 Dispose。

NotifyIcon 初始化必须设置 Icon 属性,否则托盘图标不显示
很多新手写完 NotifyIcon 代码却看不到图标,根本原因是没给 Icon 属性赋值——哪怕只是临时用系统默认图标,也得显式指定。Windows 要求托盘图标必须有有效的 Icon 实例,空引用或未初始化的 Icon 都会被静默忽略。
- 推荐用
System.Drawing.SystemIcons.Application快速测试,例如:notifyIcon1.Icon = System.Drawing.SystemIcons.Application; - 正式项目建议嵌入 .ico 文件资源:右键项目 → “添加 → 现有项”,选中图标(确保是 .ico 格式,且含 16×16 尺寸),设其“生成操作”为
Embedded Resource,再用Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location)或Properties.Resources.xxx加载 - 别在窗体构造函数里只 new NotifyIcon() 就完事,漏掉
Icon和Visible = true是最常见双坑
窗体最小化时自动隐藏到托盘,需拦截 SizeChanged + 判断 WindowState
单纯设 notifyIcon1.Visible = true 不会让窗体“最小化即隐藏”,必须手动拦截状态变化。关键不是靠 Form.WindowState 的 setter,而是监听 SizeChanged 事件,在窗口变最小化时主动隐藏窗体,并显示托盘图标。
- 在窗体设计器或构造函数中绑定:
this.SizeChanged += (s, e) => { if (this.WindowState == FormWindowState.Minimized) { this.Hide(); notifyIcon1.Visible = true; } }; - 注意:不能只靠
Form.Resize,它在最大化/还原时也会触发,必须严格比对WindowState - 如果用户从任务栏右键“最小化”,
SizeChanged仍会触发,逻辑一致;但若用快捷键Win+D显示桌面,再点托盘图标还原,需额外处理notifyIcon1.DoubleClick
双击托盘图标还原窗体,要同时处理 Show、Activate 和 WindowState
只调 form.Show() 不够——窗体可能被其他程序遮挡,或处于非激活状态,用户感知上“像没反应”。真正可用的还原逻辑必须三步并作一步。
- 在
notifyIcon1.DoubleClick中写:this.Show(); this.Activate(); this.WindowState = FormWindowState.Normal; - 缺
Activate():窗体虽可见,但焦点不在它身上,键盘输入无效 - 缺
WindowState = Normal:如果之前是最大化后最小化,还原时可能卡在“最小化”状态,实际窗体尺寸异常小 - 补充:如果窗体设置了
TopMost = true,还原后可加this.TopMost = false;再this.TopMost = true;强制置顶一次,避免被系统级窗口压住
关闭窗体时托盘图标残留?必须手动设 Visible = false 并释放资源
NotifyIcon 不随窗体销毁自动清理,关窗后图标常驻托盘,右键菜单还能点——这是资源泄漏的典型表现。.NET 5+ 默认启用了 GC 对 NotifyIcon 的终结器,但不可依赖,尤其在调试或快速重启时极易复现残留。
- 在窗体
FormClosing事件中加:notifyIcon1.Visible = false; notifyIcon1.Dispose(); - 别只写
Dispose():如果Visible还是true,系统可能延迟回收,用户眼见图标还在 - 如果用了上下文菜单(
ContextMenu或ContextMenuStrip),也要一并Dispose(),否则菜单项可能响应失效或引发 ObjectDisposedException - 调试时可在任务管理器“详细信息”页查
explorer.exe的“托盘通知区域”进程内存占用,异常增长说明NotifyIcon未释放
托盘功能看似简单,但 Icon 初始化、状态同步时机、资源释放顺序这三个点,任意一个出错都会导致“图标不出现”“点不还原”“关不干净”——它们不是孤立步骤,而是一条必须严丝合缝的链。











