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