English 中文(简体)
如何强制只允许在掩码文本框中输入数字值?
原标题:How to Force only numeric values be allowed in maskedtextbox?

我对Winforms相当新, 我想知道如何使用蒙面文本框来确保用户只输入数字值( 包括十进制值) 。

我尝试了使用“/[-+]? [0-9]+(.[9-9]+)?$/”的蒙面功能,但没有成功。即使用普通文本框,我想要的是只允许数字/十进制值

最佳回答

我调整了这个数字文本框控制 : http://sanity-free.org/forum/viewtop.php?pid=1205#p1205

如果您想要将它与工具箱分开, 您可能会在文本框的基础上创建一个新的控件, 并将该链接中的代码粘贴到代码部分 。

这是我的版本,我不知道我花了多少时间修改它。

< 坚固> ummericTextBox. deigner.cs:

using System.Windows.Forms;

namespace SeaRisenLib2.Controls
{
    partial class NumericTextBox : TextBox
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
            //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        }

        #endregion
    }
}

< 坚固> ummericTextBox.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);
        /// <summary>
        /// Fired when Text changes
        /// </summary>
        public event D Changed = delegate { };

        /// <summary>
        /// Constructor of a NumericTextBox, with negative number and 2 decimals.
        /// </summary>
        public NumericTextBox()
            : this(2, true)
        {
        }

        /// <summary>
        /// Constructor with parameters
        /// </summary>
        /// <param name="decimalNumbers">number of decimals</param>
        /// <param name="hasNegatives">has negatives</param>
        public NumericTextBox(int decimalNumbers, bool hasNegatives)
            : base()
        {
            InitializeComponent();
            DecimalNumbers = decimalNumbers;
            HasNegatives = hasNegatives;
            Format = Format;
        }

        /// <summary>
        /// Property of decimalNumbers
        /// </summary>
        public int DecimalNumbers
        {
            get
            {
                return decimalNumbers;
            }
            set
            {
                decimalNumbers = value > 0 ? value : 0;
            }
        }

        /// <summary>
        /// Bindable Decimal Text
        /// </summary>
        public decimal DecimalText
        {
            get {
                if(string.IsNullOrEmpty(Text))
                    return 0;

                return Convert.ToDecimal(Text);
            }
            set { Text = value.ToString(); }
        }

        /// <summary>
        /// The string text value of the numeric text, use DecimalText to get the numeric value.
        /// </summary>
        public override string Text
        {
            get { return base.Text; }
            set
            {
                base.Text = value;
                Changed(this);
            }
        }

        /// <summary>
        /// Property of hasNegatives
        /// </summary>
        public bool HasNegatives
        {
            get
            {
                return hasNegatives;
            }
            set
            {
                hasNegatives = value;
            }
        }

        /// <summary>
        /// Property of format
        /// </summary>
        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 += "$";
            }
        }

        /// <summary>
        /// Method PreProcessMessage
        /// </summary>
        /// <param name="msg">ref Message</param>
        /// <returns>bool</returns>
        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);
            }
        }

        /// <summary>
        /// Method WndProc
        /// </summary>
        /// <param name="m">ref Message</param>
        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);
        }

        /// <summary>
        /// Method OnKeyPress
        /// </summary>
        /// <param name="e">KeyPressEventArgs</param>
        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 ==   
                    || e.KeyChar ==  	 
                    || 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;
            }
        }

        /// <summary>
        /// Method OnTextChanged
        /// </summary>
        /// <param name="e">System.EventArgs</param>
        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);
        }

        /// <summary>
        /// Method for validate text with format
        /// </summary>
        /// <param name="text">text</param>
        /// <returns>is valid format</returns>
        private bool isValidadFormat(string text)
        {
            return Regex.IsMatch(text, Format);
        }

        /// <summary>
        /// Method for get deciamal separator
        /// </summary>
        /// <returns>Decimal Separator of current culture</returns>
        private string getDecimalSeparator()
        {
            return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
        }

        /// <summary>
        /// Method for get negative sign
        /// </summary>
        /// <returns>Negative Sign of current culture</returns>
        private string getNegativeSign()
        {
            return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NegativeSign;
        }

        /// <summary>
        /// Method for get posible resulting text for input text
        /// </summary>
        /// <param name="text">string with input text</param>
        /// <returns>posible text</returns>
        private string getPosibleText(string text)
        {
            string rText;
            rText = this.Text.Substring(0, SelectionStart);
            rText += text;
            rText += this.Text.Substring(SelectionStart + SelectionLength);
            return rText;
        }

        /// <summary>
        /// Method for get int value of text
        /// </summary>
        /// <returns>int value</returns>
        public int getIntValue()
        {
            try
            {
                return (int)getFloatValue();
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// Method for get round int value of text
        /// </summary>
        /// <returns>round int value</returns>
        public int getIntRoundValue()
        {
            try
            {
                return (int)Math.Round(getFloatValue());
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// Method for get float value of text
        /// </summary>
        /// <returns>float value</returns>
        public float getFloatValue()
        {
            try
            {
                return float.Parse(this.Text);
            }
            catch
            {
                return 0;
            }
        }


    }
}
问题回答

为什么不只是使用数字向下?设置您的最大值和分钟值,小数位数,然后离开。

< a href=" "http://msdn.microsoft.com/ en- us/library/ system. windowows.forms.numbericupdun%28v=vs.90%29.aspx" rel="nreferrer" >http://msdn.microsoft.com/ en- us/library/ system.windows.forms.nudicupown%28v=vs.90%29.aspx

掩码文本框的遮罩不是正方形图案; 它们使用自己的语法 。

您想要的图案可能是“ 999, 990.99999 ” 。 这要求用户输入至少一位数, 但用户可以输入 0 到 999, 999.999 的任意数字, 并输入最高为 4 位小数的精确度, 必要时会自动插入千位分隔符 。

您可以做的另一件事情, 类似于蒙面文本框本身所做的, 就是推翻 OnKeyPress 拒绝任何输入的字符, 导致 Regex 不匹配 :

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

您在定义模式时必须小心, 因为只有在输入到的参数与模式相符时才会有效。 但是, 如果您使用像 < code> 这样的模式, [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]+$";
        }
    }
}




相关问题
Bring window to foreground after Mutex fails

I was wondering if someone can tell me what would be the best way to bring my application to the foreground if a mutex was not able to be created for a new instance. E.g.: Application X is running ...

How to start WinForm app minimized to tray?

I ve successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

Handle DataTable.DataRow cell change event

I have a DataTable that has several DataColumns and DataRow. Now i would like to handle an event when cell of this DataRow is changed. How to do this in c#?

Apparent Memory Leak in DataGridView

How do you force a DataGridView to release its reference to a bound DataSet? We have a rather large dataset being displayed in a DataGridView and noticed that resources were not being freed after the ...

ALT Key Shortcuts Hidden

I am using VS2008 and creating forms. By default, the underscore of the character in a textbox when using an ampersand is not shown when I run the application. ex. "&Goto Here" is not ...

WPF-XAML window in Winforms Application

I have a Winforms application coded in VS C# 2008 and want to insert a WPF window into the window pane of Winforms application. Could you explain me how this is done.

热门标签