Winforms Windows窗体中的十进制文本框

Winforms Windows窗体中的十进制文本框,winforms,controls,input,maked-textbox,Winforms,Controls,Input,Maked Textbox,我正在做一个金融Winforms应用程序,在控件方面遇到了一些问题 我的客户需要在所有地方插入十进制值(价格、折扣等),我希望避免重复验证 因此,如果不是因为焦点和面具的长度,我立即尝试了适合我需要的面具TextBox(带有“00000.00欧元”这样的面具) 我无法预测我的客户将进入应用程序的数字有多大 我也不能期望他从00开始,直到逗号。一切都应该是键盘友好的 使用标准Windows窗体控件,我是否遗漏了一些东西,或者根本没有办法(除了编写自定义控件)实现这一点?您将需要一个自定义控件。只需

我正在做一个金融Winforms应用程序,在控件方面遇到了一些问题

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

因此,如果不是因为焦点和面具的长度,我立即尝试了适合我需要的面具TextBox(带有“00000.00欧元”这样的面具)

我无法预测我的客户将进入应用程序的数字有多大

我也不能期望他从00开始,直到逗号。一切都应该是键盘友好的


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

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

MSDN:

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

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


您只需要让数字和十进制符号通过,并避免使用双十进制符号。作为额外的,这会自动在起始十进制数之前添加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);
    }
}

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

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


}

拥有一个随时可用的自定义控件将在他需要连接的任何地方为他节省大量样板代码:这是一件好事。谢谢。。这让我面临下一个挑战。。创建自定义控件gg..非常感谢。我用一个自定义控件实现了这一点,并在博客上发表了相关文章:答案不错,但不支持复制粘贴(blocks ctrl+v/c)。简单的解决方案是删除
OnKeyPress
覆盖,并在
OnTextChanged
顶部添加以下内容以清除字符<代码>this.Text=Regex.Replace(this.Text,[^.0-9],”)
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);
    }


}