| 控制項 | 名稱 | 關鍵屬性 |
| PictureBox | picIcon | SizeMode=Zoom, Dock=Left |
| Label | lblMsg | AutoSize=False, Dock=Fill, TextAlign=MiddleLeft, Font=微軟正黑體 12pt |
| Panel (單按鈕) | pnlOk | Dock=Bottom, Visible=False |
| Button | btnOk | Text="確定(&O)", DialogResult=OK, Dock=Right |
| Panel (雙按鈕) | pnlYesNo | Dock=Bottom, Visible=False |
| Button | btnYes | Text="是(&Y)", DialogResult=Yes, Dock=Left |
| Button | btnNo | Text="否(&N)", DialogResult=No, Dock=Right |
二、列舉與建構函式
public enum MsgStyle { Info, Question, Error }
public partial class FrmMessageBox : Form {
public FrmMessageBox(MsgStyle style, string message) {
InitializeComponent();
// 圖示與標題
switch (style) {
case MsgStyle.Info:
picIcon.Image = Properties.Resources.info; // 專案資源加入 info.png
Text = "提示";
pnlOk.Visible = true; pnlYesNo.Visible = false;
break;
case MsgStyle.Question:
picIcon.Image = Properties.Resources.question;
Text = "詢問";
pnlOk.Visible = false; pnlYesNo.Visible = true;
break;
case MsgStyle.Error:
picIcon.Image = Properties.Resources.error;
Text = "錯誤";
pnlOk.Visible = true; pnlYesNo.Visible = false;
break;
}
lblMsg.Text = message;
AdjustSize(message);
}
// 依文字寬度自動調整表單與按鈕寬度
private void AdjustSize(string msg) {
using (var g = CreateGraphics()) {
var sz = TextRenderer.MeasureText(msg, lblMsg.Font);
int minW = 300, maxW = 800;
int w = Math.Min(Math.Max(sz.Width + 130, minW), maxW);
Width = w;
pnlOk.Width = pnlYesNo.Width = w - 40;
btnOk.Width = w - 60;
btnYes.Width = btnNo.Width = (w - 80) / 2;
}
}
}
三、靜態輔助方法 (單行呼叫)
public static class MsgBox {
public static DialogResult Show(MsgStyle style, string msg, string title = "") {
using (var box = new FrmMessageBox(style, msg)) {
if (!string.IsNullOrEmpty(title)) box.Text = title;
return box.ShowDialog();
}
}
public static DialogResult Info(string msg) => Show(MsgStyle.Info, msg);
public static DialogResult Question(string msg) => Show(MsgStyle.Question, msg);
public static DialogResult Error(string msg) => Show(MsgStyle.Error, msg);
}
四、使用範例
// 簡單資訊
MsgBox.Info("資料已儲存!");
// 詢問確認
if (MsgBox.Question("確定要刪除這筆記錄?") == DialogResult.Yes) {
DeleteRecord();
}
// 錯誤提示
try { RiskyOperation(); }
catch (Exception ex) { MsgBox.Error("操作失敗:" + ex.Message); }
五、進階擴充建議
- 主題化:引入
ColorTheme 類別,支援 Light/Dark/HighContrast 三套配色,於建構函式套用。
- 圖示向量化:使用 SVG 或
FontAwesome 字型圖示,解決 DPI 縮放模糊。
- 非模態模式:加入
ShowAsync() 回傳 Task<DialogResult>,配合 await 使用。
- 自動關閉:加入
autoCloseMs 參數,內部啟動 Timer 到期自動 Close()。
- 本地化:按鈕文字、標題從資源檔
.resx 讀取,支援多語系。
六、常見問題
| 問題 | 解決 |
| ShowDialog() 回傳 Cancel | 確認按鈕 DialogResult 屬性正確設定,且 Form.AcceptButton/CancelButton 指向對應按鈕 |
| 長文字被截斷 | lblMsg.AutoSize=False + Dock=Fill + AdjustSize() 計算寬度 |
| 多執行緒呼叫 UI 凍結 | 使用 Invoke 或 BeginInvoke 切換到 UI 執行緒建立表單 |
結語
自訂 MessageBox 不僅提升視覺一致性,更能整合品牌識別、無障礙設計與本地化需求。以上架構採用「表單+靜態輔助類」模式,易於維護與擴充,可直接納入專案共用程式庫。
- 上一篇文章: MSP430G2553 + HC-SR04 超音波測距 + UART 傳輸完整實作
- 下一篇文章: C# 裝箱與拆箱深度解析:記憶體模型與效能影響
Copyright ©
程式碼之家 All Rights Reserved