| 方案 | 實現難度 | 支援貼上驗證 | 支援負數/小數/千分位 | 適用場景 |
|---|---|---|---|---|
| 1. ES_NUMBER 風格 | ⭐ | ❌ | ❌ | 極簡整數輸入 |
| 2. KeyDown/KeyPress 驗證 | ⭐⭐ | ❌ | 可擴充 | 需自訂規則(如十六進位) |
| 3. MaskedTextBox | ⭐ | ✅ | ✅ (遮罩模式) | 固定格式(電話、IP、金額) |
| 4. NumericUpDown | ⭐ | ✅ | ✅ (內建) | 範圍限制、步進調整 |
| 5. 繼承 TextBox 重寫 CreateParams | ⭐⭐ | ❌ | ❌ | 可複用元件庫 |
public class NumericTextBox : TextBox
{
private const int ES_NUMBER = 0x2000;
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.Style |= ES_NUMBER;
return cp;
}
}
}
// 使用:this.Controls.Add(new NumericTextBox { Dock = DockStyle.Fill });
原理:設定 Windows 編輯控制項風格,系統自動攔截非數字鍵。缺點:Ctrl+V 貼上非數字仍會進入(但不顯示),需額外處理 TextChanged。
private bool nonNumber;
private void txt_KeyDown(object sender, KeyEventArgs e)
{
nonNumber = !(e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9 ||
e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9 ||
e.KeyCode == Keys.Back);
}
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
if (nonNumber) e.Handled = true;
}
可擴充支援負號、小數點、Hex 字元等。
var mtb = new MaskedTextBox
{
Mask = "999,999.00", // 6 位整數、千分位、2 位小數
PromptChar = ' ',
InsertKeyMode = InsertKeyMode.Overwrite
};
mtb.MaskInputRejected += (s, e) => toolTip.Show("僅限數字", mtb, 2000);
優點:視覺提示(佔位符)、自動插入分隔符、貼上自動過濾。
var nud = new NumericUpDown
{
Minimum = 0,
Maximum = int.MaxValue,
DecimalPlaces = 2,
ThousandsSeparator = true,
Increment = 1,
Value = 100
};
// 取值:nud.Value (decimal)
內建上下鍵步進、範圍限制、千分位、鍵盤輸入驗證,零程式碼即達生產級。
NumericTextBox、AlphanumericTextBox、DateTextBox 完整原始碼。OnKeyDown/OnTextChanged 或引用成熟庫。