如何在maskedtextbox中仅允许强制数值?
我对Winforms很新,我想知道如何使用MaskedTextBox来确保用户只输入数值(包括小数)。
我使用“/ ^ [ – +]?[0-9] +(。[0-9] +)?$ /”尝试了屏蔽function,并且没有成功。 即使使用普通的文本框,我想要的只是允许数字/小数值
我改编了这个NumericTextBox控件: http ://sanity-free.org/forum/viewtopic.php?pid = 1205#p1205
如果你想把它分开你的工具箱,你可能会创建一个基于TextBox的新控件,并将该链接中的代码粘贴到代码部分。
这是我的版本。 因为我已经有很长时间了,所以我不知道我修改了多少。
NumericTextBox.Designer.cs:
using System.Windows.Forms; namespace SeaRisenLib2.Controls { partial class NumericTextBox : TextBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; } #endregion } }
NumericTextBox.cs
// From: http://sanity-free.org/forum/viewtopic.php?pid=1205#p1205 // modified it slightly // /******************************************************/ /* NULLFX FREE SOFTWARE LICENSE */ /******************************************************/ /* NumericTextBox Library */ /* by: Steve Whitley */ /* © 2005 NullFX Software */ /* */ /* NULLFX SOFTWARE DISCLAIMS ALL WARRANTIES, */ /* RESPONSIBILITIES, AND LIABILITIES ASSOCIATED WITH */ /* USE OF THIS CODE IN ANY WAY, SHAPE, OR FORM */ /* REGARDLESS HOW IMPLICIT, EXPLICIT, OR OBSCURE IT */ /* IS. IF THERE IS ANYTHING QUESTIONABLE WITH REGARDS */ /* TO THIS SOFTWARE BREAKING AND YOU GAIN A LOSS OF */ /* ANY NATURE, WE ARE NOT THE RESPONSIBLE PARTY. USE */ /* OF THIS SOFTWARE CREATES ACCEPTANCE OF THESE TERMS */ /* */ /* USE OF THIS CODE MUST RETAIN ALL COPYRIGHT NOTICES */ /* AND LICENSES (MEANING THIS TEXT). */ /* */ /******************************************************/ /* Changed by Carlos Montiers */ /* Decimal separator "." or "," depending on locale */ /* Constructor for numericTextBox whith or without */ /* negative range and number of decimals. */ /* Does not allow the entry of non-numeric character */ /* through alt + ascii code */ /* Permit use of tab key */ /* Version: 24-10-2008 */ /******************************************************/ using System; using System.Drawing; using System.Windows.Forms; using System.Text.RegularExpressions; namespace SeaRisenLib2.Controls { public partial class NumericTextBox : TextBox { private const int WM_KEYDOWN = 0x0100; private const int WM_PASTE = 0x0302; private int decimalNumbers; private bool hasNegatives; private string format; public delegate void D(NumericTextBox sender); /// /// Fired when Text changes /// public event D Changed = delegate { }; /// /// Constructor of a NumericTextBox, with negative number and 2 decimals. /// public NumericTextBox() : this(2, true) { } /// /// Constructor with parameters /// /// number of decimals /// has negatives public NumericTextBox(int decimalNumbers, bool hasNegatives) : base() { InitializeComponent(); DecimalNumbers = decimalNumbers; HasNegatives = hasNegatives; Format = Format; } /// /// Property of decimalNumbers /// public int DecimalNumbers { get { return decimalNumbers; } set { decimalNumbers = value > 0 ? value : 0; } } /// /// Bindable Decimal Text /// public decimal DecimalText { get { if(string.IsNullOrEmpty(Text)) return 0; return Convert.ToDecimal(Text); } set { Text = value.ToString(); } } /// /// The string text value of the numeric text, use DecimalText to get the numeric value. /// public override string Text { get { return base.Text; } set { base.Text = value; Changed(this); } } /// /// Property of hasNegatives /// public bool HasNegatives { get { return hasNegatives; } set { hasNegatives = value; } } /// /// Property of format /// public string Format { get { return format; } set { format = "^"; format += HasNegatives ? "(\\" + getNegativeSign() + "?)" : ""; format += "(\\d*)"; if (DecimalNumbers > 0) { format += "(\\" + getDecimalSeparator() + "?)"; for (int i = 1; i <= DecimalNumbers; i++) { format += "(\\d?)"; } } format += "$"; } } /// /// Method PreProcessMessage /// /// ref Message /// bool public override bool PreProcessMessage(ref Message msg) { if (msg.Msg == WM_KEYDOWN) { Keys keys = (Keys)msg.WParam.ToInt32(); bool numbers = ModifierKeys != Keys.Shift && (keys >= Keys.D0 && keys <= Keys.D9 || (keys >= Keys.NumPad0 && keys <= Keys.NumPad9)); bool dec = ModifierKeys != Keys.Shift && (keys == Keys.Decimal || keys == Keys.Oemcomma || keys == Keys.OemPeriod); bool negativeSign = (keys == Keys.OemMinus && ModifierKeys != Keys.Shift) || keys == Keys.Subtract; bool home = keys == Keys.Home; bool end = keys == Keys.End; bool ctrlZ = keys == Keys.Z && ModifierKeys == Keys.Control; bool ctrlX = keys == Keys.X && ModifierKeys == Keys.Control; bool ctrlC = keys == Keys.C && ModifierKeys == Keys.Control; bool ctrlV = keys == Keys.V && ModifierKeys == Keys.Control; bool del = keys == Keys.Delete; bool bksp = keys == Keys.Back; bool tab = keys == Keys.Tab; bool arrows = keys == Keys.Up || keys == Keys.Down || keys == Keys.Left || keys == Keys.Right; if (numbers || del || bksp || arrows || home || end || ctrlC || ctrlX || ctrlV || ctrlZ) { return false; } else { if (dec) { return DecimalNumbers <= 0; } else { if (negativeSign) { return !HasNegatives; } else { if (tab) { return base.PreProcessMessage(ref msg); } else { return true; } } } } } else { return base.PreProcessMessage(ref msg); } } /// /// Method WndProc /// /// ref Message protected override void WndProc(ref Message m) { if (m.Msg == WM_PASTE) { IDataObject obj = Clipboard.GetDataObject(); string input = (string)obj.GetData(typeof(string)); string pasteText = getPosibleText(input); if (!isValidadFormat(pasteText)) { m.Result = (IntPtr)0; return; } } base.WndProc(ref m); } /// /// Method OnKeyPress /// /// KeyPressEventArgs protected override void OnKeyPress(KeyPressEventArgs e) { base.OnKeyPress(e); string keyInput = e.KeyChar.ToString(); string inputText = getPosibleText(keyInput); if (Char.IsDigit(e.KeyChar) || keyInput.Equals(getDecimalSeparator()) || keyInput.Equals(getNegativeSign())) { e.Handled = !isValidadFormat(inputText); } else if (e.KeyChar == '\b' || e.KeyChar == '\t' || keyInput.Equals(Keys.Delete.ToString()) || keyInput.Equals(Keys.Home.ToString()) || keyInput.Equals(Keys.End.ToString())) { //Allow backspace, tab, delete, home, end } else if (e.KeyChar == 26 || e.KeyChar == 24 || e.KeyChar == 3 || e.KeyChar == 22) { // 26 : Allow Ctrl+Z | 24 : Allow Ctrl+X // 3 : Allow Ctrl+C | 22 : Allow Ctrl+V } else { //Disallow e.Handled = true; } } /// /// Method OnTextChanged /// /// System.EventArgs protected override void OnTextChanged(System.EventArgs e) { if (getFloatValue() < 0) { this.ForeColor = Color.Red; } else { this.ForeColor = Color.Black; } //If the decimal point is preceded by a no number is added zero if (this.Text.StartsWith(getNegativeSign() + getDecimalSeparator())) { this.Text = getNegativeSign() + "0" + this.Text.Substring(1); this.Select(3, 0); } else { if (this.Text.StartsWith(getDecimalSeparator())) { this.Text = "0" + this.Text; this.Select(2, 0); } } base.OnTextChanged(e); } /// /// Method for validate text with format /// /// text /// is valid format private bool isValidadFormat(string text) { return Regex.IsMatch(text, Format); } /// /// Method for get deciamal separator /// /// Decimal Separator of current culture private string getDecimalSeparator() { return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; } /// /// Method for get negative sign /// /// Negative Sign of current culture private string getNegativeSign() { return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NegativeSign; } /// /// Method for get posible resulting text for input text /// /// string with input text /// posible text private string getPosibleText(string text) { string rText; rText = this.Text.Substring(0, SelectionStart); rText += text; rText += this.Text.Substring(SelectionStart + SelectionLength); return rText; } /// /// Method for get int value of text /// /// int value public int getIntValue() { try { return (int)getFloatValue(); } catch { return 0; } } /// /// Method for get round int value of text /// /// round int value public int getIntRoundValue() { try { return (int)Math.Round(getFloatValue()); } catch { return 0; } } /// /// Method for get float value of text /// /// float value public float getFloatValue() { try { return float.Parse(this.Text); } catch { return 0; } } } }
为什么不使用NumericUpDown? 设置最大值和最小值,小数位数,然后离开。
http://msdn.microsoft.com/en-us/library/system.windows.forms.numericupdown%28v=vs.90%29.aspx
MaskedTextBox的掩码不是正则表达式模式; 他们使用自己的语法。
你想要的模式可能就像“999,990.9999”。 这要求用户输入至少一个数字,但是他们可以输入0到999,999.9999之间的任何数字,精度最多为4位小数,并在需要时自动插入千位分隔符。
您可以做的另一件事,类似于MaskedTextBox本身所做的,是覆盖OnKeyPress以拒绝任何导致正则表达式不匹配的字符:
public class RegexTextBox:TextBox { [Category("Behavior")] public string RegexPattern {get;set;} protected override OnKeyPress(KeyPressEventArgs e) { if (!Regex.IsMatch(this.Text + e.KeyChar, RegexPattern)) e.Handled = true; else base.OnKeyPress(e); } }
在定义模式时必须要小心,因为它只有在到目前为止输入的内容与模式匹配时才有效。 但是,如果你使用像"[0-9]{1,3}((,[0-9]{1,3})*(\.[0-9]*)?"
这样的模式,它将适用于你的情况"[0-9]{1,3}((,[0-9]{1,3})*(\.[0-9]*)?"
谢谢,下面的工作代码。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; namespace System.Windows.Forms { public class RegexTextBox : TextBox { [Category("Behavior")] public string RegexPattern { get; set; } private bool DelOrBack = false; protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete) { DelOrBack = true; } } protected override void OnKeyPress(KeyPressEventArgs e) { if (!Regex.IsMatch(this.Text + e.KeyChar, RegexPattern) && !DelOrBack) { e.Handled = true; } else { base.OnKeyPress(e); } DelOrBack = false; } } public class NumericTextBox : RegexTextBox { public NumericTextBox() { RegexPattern = "^[0-9]+$"; } } }