代码之家  ›  专栏  ›  技术社区  ›  Tigraine

Windows窗体中的十进制文本框

  •  4
  • Tigraine  · 技术社区  · 16 年前

    我正在做一个财务WinForms应用程序,在控制方面遇到了一些问题。

    我的客户需要在各处插入十进制值(价格、折扣等),我希望避免重复验证。

    因此,如果不是为了焦点和面具的长度,我立即尝试了适合我需要的蒙面文本框(带有一个“_∙0000000”这样的面具)。

    我无法预测我的客户会在应用程序中输入多少数字。

    我也不能指望他以00开头就可以得到逗号。一切都应该是键盘友好型的。

    我是否遗漏了一些东西,或者根本没有办法(除了编写一个自定义控件)用标准的Windows窗体控件来实现这一点?

    6 回复  |  直到 6 年前
        1
  •  5
  •   Abel Gaxiola    16 年前

    这两个重写方法是为我做的(免责声明:此代码尚未投入生产)。您可能需要修改)

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (!char.IsNumber(e.KeyChar) & (Keys)e.KeyChar != Keys.Back 
                & e.KeyChar != '.')
            {
                e.Handled = true;
            }
    
            base.OnKeyPress(e);
        }
    
        private string currentText;
    
        protected override void OnTextChanged(EventArgs e)
        {
            if (this.Text.Length > 0)
            {
                float result;
                bool isNumeric = float.TryParse(this.Text, out result);
    
                if (isNumeric)
                {
                    currentText = this.Text;
                }
                else
                {
                    this.Text = currentText;
                    this.Select(this.Text.Length, 0);
                }
            }
            base.OnTextChanged(e);
        }
    
        2
  •  5
  •   Nick    16 年前

    您将需要自定义控件。只需在控件上捕获验证事件,并检查字符串输入是否可以解析为十进制。

        3
  •  3
  •   nportelli    16 年前

    我认为您不需要自定义控件,只需为验证事件编写一个十进制验证方法,并将其用于需要验证的所有位置。别忘了包括 NumberFormatInfo 它将处理逗号和numebr符号。

        4
  •  1
  •   Rockcoder    16 年前
        5
  •  0
  •   Halvor Holsten Strand mtorres    10 年前

    您只需要让数字和十进制符号通过,并避免使用双十进制符号。作为一个额外的,这会自动在开始的十进制数之前添加一个0。

    public class DecimalBox : TextBox
    {
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == ',')
            {
                e.KeyChar = '.';
            }
    
            if (!char.IsNumber(e.KeyChar) && (Keys)e.KeyChar != Keys.Back && e.KeyChar != '.')
            {
                e.Handled = true;
            }
    
            if(e.KeyChar == '.' )
            {
                if (this.Text.Length == 0)
                {
                    this.Text = "0.";
                    this.SelectionStart = 2;
                    e.Handled = true;
                }
                else if (this.Text.Contains("."))
                {
                    e.Handled = true;
                }
            }
    
            base.OnKeyPress(e);
        }
    }
    
        6
  •  0
  •   clamchoda    6 年前

    另一种方法是阻止不需要的内容,并在完成后格式化。

    class DecimalTextBox : TextBox
    {
        // Handle multiple decimals
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == '.')
                if (this.Text.Contains('.'))
                    e.Handled = true;
    
            base.OnKeyPress(e);
        }
    
        // Block non digits
        // I scrub characters here instead of handling in OnKeyPress so I can support keyboard events (ctrl + c/v/a)
        protected override void OnTextChanged(EventArgs e)
        {
            this.Text = System.Text.RegularExpressions.Regex.Replace(this.Text, "[^.0-9]", "");
            base.OnTextChanged(e);
        }
    
        // Apply our format when we're done
        protected override void OnLostFocus(EventArgs e)
        {
            if (!String.IsNullOrEmpty(this.Text))
                this.Text = string.Format("{0:N}", Convert.ToDouble(this.Text));
    
            base.OnLostFocus(e);
        }
    
    
    }