C#文本框中的负数

本文关键字:文本 | 更新日期: 2023-09-27 18:21:12

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

    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

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

C#文本框中的负数

试试这个:

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,但它有点糟糕,即使上面的方法也没有带来好的视觉效果(当你尝试将文本粘贴到数字文本框中时,你可以看到文本正在更改并恢复到有效值)。

  1. 仅当单击某些"确定"或"提交"按钮时才评估字符,而不是每次击键时
  2. 使用正则表达式检查整个文本的有效性,而不仅仅是键入的字符
  3. 尝试使用Int64.TryParse将文本解析为long,并计算调用的bool结果
  4. 已经阅读了以上所有内容:为什么不简单地使用NumericUpDown控件

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

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

我认为依赖文本框事件是解决问题的更好方法。在任何情况下,你都可以继续使用你的方法,并用事件来补充它,以解释标题"-"的问题。此代码删除文本框中的任何短划线,除非位于第一个位置:

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

这对我有效(尽管您可能会考虑根据您想要如何处理十进制分隔符进行一些修改(因为数字格式取决于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
    }