C# WinForm 新手常遇到:點擊窗體右上角 × 關閉登錄窗,進入主窗體後再關閉主窗,程序進程仍殘留在調試狀態。根因是隱藏而非關閉登錄窗,且主窗關閉未終止消息泵。
// 登錄窗體按鈕點擊
private void button1_Click(object sender, EventArgs e) {
if (textBox1.Text == "admin" && textBox2.Text == "123") {
this.Hide(); // ❌ 僅隱藏,窗體實例仍存活,消息泵仍運行
MainFir mf = new MainFir();
mf.Show(); // 非模態顯示主窗
}
}
// 主窗體關閉時,程序不退出,因為登錄窗體仍在運行
// Program.cs 入口點修改
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// 1. 先顯示登錄對話框 (模態)
using (LoginForm login = new LoginForm()) {
if (login.ShowDialog() == DialogResult.OK) {
// 2. 登錄成功,運行主窗體
Application.Run(new MainFir());
}
}
// 3. 登錄取消/失敗,程序自然退出
}
}
// LoginForm.cs
private void button1_Click(object sender, EventArgs e) {
if (textBox1.Text == "admin" && textBox2.Text == "123") {
this.DialogResult = DialogResult.OK; // 設置結果並關閉模態對話框
// this.Close(); // 隱含調用
} else {
MessageBox.Show("用戶名或密碼錯誤");
}
}
// MainFir.cs 主窗體
protected override void OnFormClosing(FormClosingEventArgs e) {
base.OnFormClosing(e);
// 關鍵:強制終止所有消息泵,退出進程
Application.Exit();
}
// 或在 FormClosing 事件處理器 (設計器雙擊 FormClosing 事件)
private void MainFir_FormClosing(object sender, FormClosingEventArgs e) {
Application.Exit();
}
// 登錄窗體
private void button1_Click(object sender, EventArgs e) {
if (textBox1.Text == "admin" && textBox2.Text == "123") {
this.Hide();
MainFir mf = new MainFir();
mf.ShowDialog(this); // 模態顯示,主窗關閉後返回此處
this.Close(); // 關閉登錄窗,程序退出
}
}
| 事件 | 觸發時機 | 可取消關閉 | 典型用途 |
|---|---|---|---|
| FormClosing | 關閉開始前 | ✅ e.Cancel = true | 確認保存、驗證權限、清理資源 |
| FormClosed | 關閉完成後 | ❌ | 釋放非托管資源、記錄日誌 |
private void Form1_FormClosing(object sender, FormClosingEventArgs e)Application.Run(mainForm),僅一個主窗體控制進程生命週期ShowDialog() 模態顯示,返回 DialogResult 決定是否啟動主窗Application.Exit() 確保所有消息泵終止Hide() 代替 Close() 作為窗體切換手段規範窗體生命週期管理,是 WinForm 開發穩定性的基石。