【问题标题】:Decimal Textbox in Windows FormsWindows 窗体中的十进制文本框
【发布时间】:2010-09-19 14:23:22
【问题描述】:

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

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

所以我立即尝试了适合我需要的 MaskedTextBox(使用像“€ 00000.00”这样的掩码),如果不是因为焦点和掩码的长度。

我无法预测我的客户将输入应用程序的数量有多大。

我也不能指望他以 00 开始所有内容以到达逗号。一切都应该是键盘友好的。

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

【问题讨论】:

    标签: winforms controls input maked-textbox


    【解决方案1】:

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

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

    【讨论】:

    • 非常感谢。我使用自定义控件实现了这一点,并在博客中对此进行了介绍:tigraine.at/2008/10/28/decimaltextbox-for-windows-forms
    • 不错的答案,但不支持复制粘贴(块 ctrl + v/c)
    • 简单的解决方案是删除OnKeyPress覆盖并将以下内容添加到OnTextChanged的顶部以清除字符。 this.Text = Regex.Replace(this.Text, "[^.0-9]", "");
    【解决方案2】:

    您将需要一个自定义控件。只需捕获控件上的 Validating 事件并检查字符串输入是否可以解析为小数。

    【讨论】:

    • 谢谢..这让我面临下一个挑战..创建一个自定义控件gg ..
    【解决方案3】:

    我认为您不需要自定义控件,只需为验证事件编写一个小数验证方法,并将其用于您需要验证的所有地方。不要忘记包含NumberFormatInfo,它将处理逗号和数字符号。

    【讨论】:

    • 准备好一个自定义控件可以为他节省一堆样板代码,无论他需要连接它的地方:这是一件好事。
    【解决方案4】:
    【解决方案5】:

    您只需要让数字和小数符号通过,避免使用双小数符号。另外,这会在开始的十进制数字前自动添加一个 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】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 2018-03-01
        • 2011-10-16
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多