3

我已经完成了这里的问题,并找到了使文本框只接受开头带有一个小数和负号的数值的答案。

    if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.' && e.KeyChar != '-')
    {
        e.Handled = true;
    }

    // only allow one decimal point
    if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
    {
        e.Handled = true;
    }

    if (e.KeyChar == '-' && (sender as TextBox).Text.Length > 0)
    {
        e.Handled = true;
    }

但是我确实有一个问题。假设用户输入了一个数字:

123455789764

然后他意识到这个数字是负数。他回到开头并尝试输入负号,却发现它不起作用。有没有办法解决这个问题,而不是让用户删除他输入的数字,添加负数并再次重新输入数字?

4

5 回答 5

3

尝试这个:

Regex reg = new Regex(@"^-?\d+[.]?\d*$");
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (char.IsControl(e.KeyChar)) return;
        if (!reg.IsMatch(textBox1.Text.Insert(textBox1.SelectionStart, e.KeyChar.ToString()) + "1")) e.Handled = true;
    }

对于keyboardP的建议,我添加了这段代码以完全防止非数字值,我认为你应该尝试TextBox.ShortcutsEnabled = false;,因为我认为用户不需要任何类型的复制和粘贴数字数据。

    Regex reg = new Regex(@"^-?\d+[.]?\d*$");
    bool textChangedByKey;
    string lastText;
    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (char.IsControl(e.KeyChar)) return;
        if (!reg.IsMatch(textBox1.Text.Insert(textBox1.SelectionStart, e.KeyChar.ToString()) + "1"))
        {
            e.Handled = true;
            return;
        }
        textChangedByKey = true;
    }
    private void textBox1_TextChanged(object sender, EventArgs e)
    {            
        if (!textChangedByKey)
        {
            if (!reg.IsMatch(textBox1.Text))
            {
                textBox1.Text = lastText;
                return;
            }                
        }
        else textChangedByKey = false;
        lastText = textBox1.Text;
    }

我尝试过使用Undo()一些重置SelectedText的方法,但是它有点糟糕,即使上面的方式也没有带来很好的视觉效果(尝试将文本粘贴到数字文本框中时,您可以看到文本更改并恢复为有效值) .

于 2013-07-04T09:34:24.943 回答
1
  1. 仅在单击某些“确定”或“提交”按钮时评估字符,而不是在每次击键时评估字符
  2. 使用正则表达式检查整个文本的有效性,而不仅仅是键入的字符
  3. 尝试将文本解析为longusingInt64.TryParse并评估bool调用结果。
  4. 阅读完以上所有内容:为什么不简单地使用NumericUpDown控件?
于 2013-07-04T09:41:03.000 回答
0

这对我有用(尽管您可能会根据您想要处理小数分隔符的方式考虑进行一些修改(因为数字格式取决于 CurrentCulture 设置)

这只接受数字,输入的长度和进一步的格式(例如,小数点分隔符前只允许一个数字)没有得到解决,尽管我认为可以修改它来做到这一点。

public enum NumericTextBoxType { TDecimal = 1, TByte, TShort, TInt, TLong }

    public class NumericTextBox : TextBox
    {
        #region ARRAYS

        private static readonly Keys[] separators = 
        {
        Keys.Decimal,
        Keys.Oemcomma,
        Keys.OemPeriod
        };

        private static readonly Keys[] allowed =
        {
        Keys.D1,
        Keys.D2,
        Keys.D3,
        Keys.D4,
        Keys.D5,
        Keys.D6,
        Keys.D7,
        Keys.D8,
        Keys.D9,
        Keys.D0,
        Keys.NumPad0,
        Keys.NumPad1,
        Keys.NumPad2,
        Keys.NumPad3,
        Keys.NumPad4,
        Keys.NumPad5,
        Keys.NumPad6,
        Keys.NumPad7,
        Keys.NumPad8,
        Keys.NumPad9,
        Keys.Decimal,
        Keys.Oemcomma,
        Keys.OemPeriod,
        Keys.OemMinus,
        Keys.Subtract,
        Keys.Back,
        Keys.Delete,
        Keys.Tab,
        Keys.Enter,
        Keys.Up,
        Keys.Down,
        Keys.Left,
        Keys.Right
        };

        private static readonly Keys[] intallowed =
        {
        Keys.D1,
        Keys.D2,
        Keys.D3,
        Keys.D4,
        Keys.D5,
        Keys.D6,
        Keys.D7,
        Keys.D8,
        Keys.D9,
        Keys.D0,
        Keys.NumPad0,
        Keys.NumPad1,
        Keys.NumPad2,
        Keys.NumPad3,
        Keys.NumPad4,
        Keys.NumPad5,
        Keys.NumPad6,
        Keys.NumPad7,
        Keys.NumPad8,
        Keys.NumPad9,
        Keys.OemMinus,
        Keys.Subtract,
        Keys.Back,
        Keys.Delete,
        Keys.Tab,
        Keys.Enter,
        Keys.Up,
        Keys.Down,
        Keys.Left,
        Keys.Right
        };

        #endregion ARRAYS

        #region PROPERTY NumericTextBoxType

        private NumericTextBoxType _NumericTextBoxType = NumericTextBoxType.TDecimal;

        public NumericTextBoxType NumericTextBoxType
        {
            get
            {
                return
                _NumericTextBoxType;
            }
            set
            {
                _NumericTextBoxType = value;
            }
        }

        #endregion PROPERTY NumericTextBoxType

        #region PROPERTY AllowMinus

        public bool AllowMinus { get; set; }

        #endregion

        string prvText = "";
        int prevSelStart = 0;

        public NumericTextBox()
            : base()
        {
            this.NumericTextBoxType = NumericTextBoxType.TDecimal;
            this.AllowMinus = true;
        }

        #region EVENT METHOD OnKeyDown

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if (e.Modifiers == Keys.Control)
            {
                prvText = this.Text;
                prevSelStart = this.SelectionStart;
                return;
            }

            // ignore not allowed
            if (NumericTextBoxType != NumericTextBoxType.TDecimal)
            {
                if (!intallowed.Contains(e.KeyCode)) e.SuppressKeyPress = true;
            }
            else
            {
                if (!allowed.Contains(e.KeyCode)) e.SuppressKeyPress = true;
                else if (separators.Contains(e.KeyCode))
                {
                    NumberFormatInfo numberFormatInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
                    string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;

                    int selLength = this.SelectionLength;
                    int selStart = this.SelectionStart;

                    if (!this.Text.Remove(selStart, selLength).Contains(decimalSeparator))
                    {
                        this.Text = this.Text
                        .Remove(selStart, selLength)
                        .Insert(this.SelectionStart, decimalSeparator);
                        this.SelectionStart = selStart + decimalSeparator.Length;
                    }
                    e.SuppressKeyPress = true;
                }
            }

            // ignore minus if not first or not allowed
            if (e.KeyCode == Keys.OemMinus || e.KeyCode == Keys.Subtract)
            {
                if (!this.AllowMinus) e.SuppressKeyPress = true;
                else if (NumericTextBoxType == NumericTextBoxType.TByte) e.SuppressKeyPress = true;
                else if (this.SelectionStart > 0) e.SuppressKeyPress = true;
            }

            prvText = this.Text;
            prevSelStart = this.SelectionStart;
        }

        #endregion EVENT METHOD OnKeyDown

        #region METHOD OnTextChanged

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);

            // don't allow incorrect paste operations
            if (Regex.IsMatch(this.Text, (!AllowMinus ? "[-" : "[") + @"^\d.,]") ||
            Regex.Matches(this.Text, @"[.,]").Count > 1)
            {
                this.Text = prvText;
                this.SelectionStart = prevSelStart;
            }
        }

        #endregion

    }
于 2013-07-04T09:51:06.020 回答
0

我认为依靠文本框事件是解决问题的更好方法。在任何情况下,您都可以继续使用您的方法并用事件来补充它以解决标题“-”问题。此代码从文本框中删除所有破折号,除非位于第一个位置:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        if (textBox1.Text.Trim().Length > 0)
        {
            if (textBox1.Text.Contains("-") && (textBox1.Text.Substring(0, 1) != "-" || textBox1.Text.Split('-').Length > 2))
            {
                bool headingDash = false;
                if (textBox1.Text.Substring(0, 1) == "-")
                {
                    headingDash = true;
                }
                textBox1.Text = textBox1.Text.Replace("-", "");
                if (headingDash)
                {
                    textBox1.Text = "-" + textBox1.Text;
                }
            }
        }
    }
于 2013-07-04T09:36:28.127 回答
0

您可以检查光标位置并在光标不是开头或已经有“-”时丢弃“-”,而不是检查字符串的长度(并在它非零时丢弃“-”)开始。

但是在提交过程中稍后进行整个检查而不是吞下击键可能是更好的用户体验。

于 2013-07-04T09:29:49.853 回答