如何在maskedtextbox中仅允许强制数值?

Rac*_*ain 5 .net c# winforms

我对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


Chu*_*age 1

我改编了这个 NumericTextBox 控件:http://sanity-free.org/forum/viewtopic.php?pid=1205 #p1205

\n\n

如果您希望将其与工具箱分开,您可能会创建一个基于 TextBox 的新控件,并将该链接中的代码粘贴到代码部分。

\n\n

这是我的版本。我不知道我修改了多少,因为我已经使用了很长时间了。

\n\n

NumericTextBox.Designer.cs:

\n\n
using 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}\n
Run 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}\n
Run Code Online (Sandbox Code Playgroud)\n