預設 Program.cs 寫法 Application.Run(new LoginForm()) 會導致:關閉登入視窗 → 整個應用程式退出。若想「關閉登入、開啟主視窗」且不結束進程,需改變應用程式上下文管理方式。
適合極簡單專案:啟動時建立主視窗但設為不可見,登入成功後「顯現」。
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
SetInvisible(); // 一開始隱形
}
private void SetInvisible()
{
this.Opacity = 0; // 完全透明
this.ShowInTaskbar = false; // 任務列不顯示
}
private void SetVisible()
{
this.Opacity = 1;
this.ShowInTaskbar = true;
this.BringToFront(); // 確保置頂
}
// 登入視窗驗證成功後呼叫
public void OnLoginSuccess() => SetVisible();
}
// Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var main = new MainForm(); // 真正的主視窗 (隱形)
var login = new LoginForm(main); // 傳入 main 參考
login.Show(); // 顯示登入視窗
Application.Run(); // 無參數 Run,靠主視窗存活控制
}
優點:代碼極少,無需理解 ApplicationContext。
缺點:主視窗實際已建立 (資源佔用),Alt+Tab 可能看到縮圖,屬於「掩耳盜鈴」。
繼承 ApplicationContext,自行決定何時結束訊息迴圈。
public class AppContext : ApplicationContext
{
private readonly LoginForm _loginForm;
private MainForm _mainForm;
public AppContext()
{
_loginForm = new LoginForm();
_loginForm.LoginSuccess += OnLoginSuccess; // 事件解耦
_loginForm.FormClosed += (s, e) => ExitThread(); // 關閉登入即退出 (未登入情況)
_loginForm.Show();
}
private void OnLoginSuccess(object sender, EventArgs e)
{
_loginForm.LoginSuccess -= OnLoginSuccess;
_loginForm.Close(); // 真正關閉登入視窗
_mainForm = new MainForm();
_mainForm.FormClosed += (s, e) => ExitThread(); // 關閉主視窗才真正退出程式
_mainForm.Show();
}
}
// Program.cs 僅一行變更
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AppContext()); // 傳入自訂 Context
}
優點:符合 WinForms 設計模式,視窗真正關閉釋放資源,任務管理器無殘留進程,支援多視窗切換邏輯擴展。
缺點:稍微增加代碼量,需理解事件驅動流程。
在 AppContext 中集中處理:登入失敗不關閉登入視窗、依角色實例化 AdminMainForm 或 UserMainForm、單一實例檢查 (Mutex) 等横切關注點,保持 Program.cs 極簡。
ApplicationContext 更是天然的導航協調者位置。