在 Windows Forms 應用程式中,模式對話框 是引導使用者完成特定任務(如設定選項、輸入資料、確認動作)的核心 UI 元件。本文系統整理模式視窗的屬性設定、按鈕交互設計、開啟/關閉流程控制、父子視窗資料傳遞七大模式,以及 .NET 內建常用對話框,助你打造專業、易用的桌面應用體驗。
透過設計師屬性視窗或程式碼設定下列屬性,即可符合 Windows UI 標準規範:
| 屬性 | 建議值 | 說明 |
|---|---|---|
StartPosition | CenterParent | 視窗置中於父視窗,避免出現在螢幕邊緣。 |
HelpButton | true | 標題列顯示說明按鈕(需搭配 HelpRequested 事件實作)。 |
MaximizeBox | false | 隱藏最大化鈕,模式視窗通常固定大小。 |
MinimizeBox | false | 隱藏最小化鈕,防止使用者誤將對話框最小化到工作列。 |
ShowIcon | false | 標題列不顯示圖示,簡化視覺。 |
ShowInTaskbar | false | 不佔用工作列空間,避免使用者透過工作列切換繞過模式限制。 |
FormBorderStyle | FixedDialog | 固定邊框不可調整大小,標題列圖示失效。 |
ControlBox | false (視需求) | 隱藏系統選單(關閉/最大化/最小化鈕),強制使用者透過確定/取消鈕關閉。 |
// 程式碼一次設定
this.StartPosition = FormStartPosition.CenterParent;
this.HelpButton = true;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
// this.ControlBox = false; // 視情況啟用
設定這兩個屬性,讓使用者能以 Enter、Esc 快速完成或取消操作:
// 設計師中拖曳兩個 Button:btnOK、btnCancel
this.AcceptButton = this.btnOK; // Enter 鍵觸發
this.CancelButton = this.btnCancel; // Esc 鍵觸發
細節提醒:
btnCancel 時按 Enter 會觸發 btnCancel 而非 btnOK。var form = new OptionForm();
// form.ShowDialog(); // 無 Owner
form.ShowDialog(this); // 指定 Owner 為 this (主視窗)
ShowDialog(IWin32Window owner):建立擁有者關係,子視窗會隨父視窗最小化/關閉、永不顯示於父視窗之後。this.Owner as MainForm 取得父視窗參考;若用無參數 ShowDialog(),Owner 為 null。ShowDialog() 回傳 DialogResult 列舉:OK、Cancel、Yes、No、Abort、Retry、Ignore、None。
// FormClosing、btnOK_Click、btnCancel_Click 三個事件處理函式
private void btnOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtPath.Text))
{
MessageBox.Show("請輸入路徑!");
txtPath.Focus();
}
else
this.DialogResult = DialogResult.OK;
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
private void OptionForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult != DialogResult.OK && this.DialogResult != DialogResult.Cancel)
e.Cancel = true; // 防止使用者點右上角 X 關閉
}
// 建構函式中設定按鈕預設 DialogResult
public OptionForm()
{
InitializeComponent();
btnOK.DialogResult = DialogResult.OK;
btnCancel.DialogResult = DialogResult.Cancel;
}
// 僅處理驗證失敗時阻止關閉
private void btnOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtPath.Text))
{
MessageBox.Show("請輸入路徑!");
txtPath.Focus();
this.DialogResult = DialogResult.None; // 關鍵:重設為 None 取消關閉
}
// 驗證通過時,btnOK.DialogResult = OK 會自動關閉視窗並回傳 OK
}
原理: 當按鈕的 DialogResult 屬性非 None 時,點擊該按鈕會自動設定表單 DialogResult 並關閉視窗。在 Click 事件中將 this.DialogResult = DialogResult.None 可中斷關閉流程。
| 模式 | 適用場景 | 範例關鍵字 |
|---|---|---|
| 1. 建構函式參數 | 必要資料、單向傳遞、型別安全 | new OptionForm(settings) |
| 2. 公開屬性 | 選擇性資料、雙向綁定、設計師可見 | form.Settings = ...; form.ShowDialog(); var result = form.SelectedPath; |
| 3. 公開方法 | 封裝邏輯、延遲初始化 | form.LoadSettings(obj); form.ShowDialog(); form.SaveSettings(); |
| 4. Form.Owner / OwnedForms | 父子視窗生命週期綁定、父視窗主動推送 | form.ShowDialog(this); var parent = this.Owner as MainForm; |
| 5. 靜態類別/全域共享 | 跨視窗、跨模組共用狀態(如登入用戶資訊) | UserSession.Current.Name = "Admin"; |
| 6. Singleton 模式 | 單一實例全域存取、線程安全 | UserLoginInfo.CurrentUserInfo.Role = "Admin"; |
| 7. 事件發布/訂閱 | 鬆耦合、即時通知、單向資料流 | form.SettingChanged += (s,e) => ...; form.ShowDialog(); |
// 1. 定義事件參數類別
public class OptionSettingEventArgs : EventArgs
{
public string ChangedPath { get; private set; }
public OptionSettingEventArgs(string path) { ChangedPath = path; }
}
// 2. 子視窗定義並引發事件
public partial class OptionForm : Form
{
public event EventHandler<OptionSettingEventArgs> OptionSettingChanged;
protected virtual void OnOptionSettingChanged(OptionSettingEventArgs e)
{
OptionSettingChanged?.Invoke(this, e);
}
private void btnBrowse_Click(object sender, EventArgs e)
{
using (var dlg = new FolderBrowserDialog())
{
if (dlg.ShowDialog(this) == DialogResult.OK && txtPath.Text != dlg.SelectedPath)
{
txtPath.Text = dlg.SelectedPath;
OnOptionSettingChanged(new OptionSettingEventArgs(dlg.SelectedPath));
}
}
}
}
// 3. 父視窗訂閱
var form = new OptionForm();
form.OptionSettingChanged += (s, e) => MessageBox.Show($"新路徑:{e.ChangedPath}");
form.ShowDialog();
| 類別 | 功能 | 繼承自 | 可繼承 |
|---|---|---|---|
MessageBox | 訊息提示、確認、錯誤 | - | 否 (static) |
OpenFileDialog | 開啟檔案 | FileDialog | 否 |
SaveFileDialog | 儲存檔案 | FileDialog | 否 |
FolderBrowserDialog | 選擇資料夾 | CommonDialog | 否 |
FontDialog | 選擇字型 | CommonDialog | 是 |
ColorDialog | 選擇顏色 | CommonDialog | 是 |
PageSetupDialog | 列印頁面設定 | CommonDialog | 否 |
PrintDialog | 列印設定 | CommonDialog | 否 |
PrintPreviewDialog | 列印預覽 | Form | 是 |
注意: 繼承自 CommonDialog 或 FileDialog 的類別,均使用 ShowDialog() 或 ShowDialog(IWin32Window) 開啟模式視窗;PrintPreviewDialog 繼承 Form,亦可用 Show() 非模式開啟。
掌握模式視窗的標準屬性、按鍵交互、關閉流程控制、資料傳遞模式與內建對話框,能讓你的 WinForms 應用擁有專業、一致且符合使用者直覺的操作體驗。實務上常採用「公開屬性 + 事件」組合,兼顧型別安全與鬆耦合。