在開發 WinForms 應用程式時,常見的需求是「啟動時隱藏主視窗,僅在系統托盤顯示圖示」。許多開發者會直覺地設定 ShowInTaskbar = false 搭配 WindowState = FormWindowState.Minimized。然而,這種方法存在一個嚴重缺陷:使用者仍可透過 Alt + Tab 切換視窗時看到該程式圖示,並將其喚回螢幕,無法達到真正的「隱形啟動」效果。
在主表單類別中覆寫 SetVisibleCore,強制將可見性參數設為 false:
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
}
優點: 程式碼極少,立竿見影隱藏視窗。
缺點: 視窗將永遠無法透過 Show() 顯示;關閉程式時必須呼叫 Application.Exit() 而非 Close(),導致主視窗的許多功能(如表單關閉事件、資源釋放邏輯)需遷移至其他處理常式,維護成本較高。
在 Program.cs 的 Main() 手動建立 NotifyIcon、ContextMenuStrip 並呼叫 Application.Run()(無參數版本)維持訊息迴圈:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var resources = new System.Resources.ResourceManager("myResource", Assembly.GetExecutingAssembly());
var ni = new NotifyIcon
{
BalloonTipIcon = ToolTipIcon.Warning,
BalloonTipText = "test!",
BalloonTipTitle = "test.",
Icon = (Icon)resources.GetObject("ni.Icon"),
Text = "Test",
Visible = true
};
ni.MouseClick += (sender, e) => ni.ShowBalloonTip(0);
// ni.ContextMenuStrip = contextMenu; // 視需求掛載右鍵選單
Application.Run(); // 無表單參數,純訊息迴圈
}
適用場景: 極簡工具、無 UI 介面的背景服務型程式。
缺點: 所有 UI 元件(選單、對話框、設定視窗)皆需手動 new 並管理生命週期,程式碼冗長且易出錯,不適合功能豐富的應用程式。
此方案完美平衡「啟動隱藏」與「隨時可顯示」兩大需求,核心邏輯如下:
OnActivated 事件將 Visible 設為 false,避免閃爍且不影響 Alt+Tab 行為。NotifyIcon.DoubleClick 事件,動態切換 Visible、ShowInTaskbar 與 WindowState,實現「雙擊顯示/隱藏」的直覺操作。private bool _windowCreated = true;
protected override void OnActivated(EventArgs e)
{
if (_windowCreated)
{
base.Visible = false; // 關鍵:啟動瞬間隱藏
_windowCreated = false;
}
base.OnActivated(e);
}
private void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
if (this.Visible)
{
this.Hide();
this.ShowInTaskbar = false;
}
else
{
this.Visible = true;
this.ShowInTaskbar = true;
this.WindowState = FormWindowState.Normal;
this.BringToFront(); // 確保置頂顯示
}
}
優勢總結:
若專案僅需單一托盤圖示且無複雜 UI,方案二最輕量;若需保留完整主視窗功能並追求最佳使用者體驗,方案三是首選。建議搭配 FormClosing 事件攔截關閉動作(改為 Hide() 並 e.Cancel = true),打造真正「常駐托盤、關閉即最小化」的專業級桌面應用。