How to Force only numeric values be allowed in maskedtextbox?

前端 未结 4 1642
栀梦
栀梦 2020-12-18 07:04

I am fairly new to Winforms, and I would like to know how to use a MaskedTextBox to ensure that only numerical values(decimals included) are entered by the user.

I

4条回答
  •  無奈伤痛
    2020-12-18 07:38

    I adapted this NumericTextBox control: http://sanity-free.org/forum/viewtopic.php?pid=1205#p1205

    If you want it apart of your toolbox, you'd probably create a new control based on a TextBox and paste the code in that link into the code section.

    Here's my version of it. I don't know how much I've modified it as I've had it a long time.

    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;
                }
            }
    
    
        }
    }
    

提交回复
热议问题