带1逗号的文本框货币格式

本文关键字:货币 格式 文本 | 更新日期: 2023-09-27 17:53:31

我在c# winforms中有一个文本框。

   private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsNumber(e.KeyChar) & (Keys)e.KeyChar != Keys.Back
                & e.KeyChar != ',')
        {
            e.Handled = true;
        }
        base.OnKeyPress(e);
    }
上面的

代码工作得很好,但是我可以添加两个逗号,如"100,00"。我怎么能只让用户添加"100,00""100,000,000"与1逗号作为货币格式?

任何帮助都将不胜感激。

谢谢。

带1逗号的文本框货币格式

不是对你实际问题的直接回答,但绝对是你应该考虑的建议:使用MaskedTextBox,而不是TextBox

MaskedTextBox具有作为文本值模式的Mask属性。在您的情况下,合适的掩码可能是#,###.##。请注意,根据程序集所在的区域性,小数点分隔符可能不是逗号。不过,您仍然可以将其转换为数值,这无疑是您想要的。

更新:

作为一个额外的建议,一些第三方供应商如devexpress提供了更高级的掩码输入控件,可以使用传统的掩码,也可以使用基于正则表达式的验证器。如果你能负担得起这笔钱,这可能是一个值得研究的东西。

正如Crono在另一个答案中所说,MaskedTextBox是最好的解决方案。但是,如果您真的想在文本框中添加约束和格式,您可以将文本解析为decimal,然后完全覆盖逗号键,只允许一个小数。

这是一个有点拼凑在一起,但应该达到你想要的:

首先创建事件处理程序,不允许逗号输入,只允许一个小数点

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        //Just don't let them type commas - We will format after the TextBox is left
        if (!char.IsControl(e.KeyChar)
            && !char.IsDigit(e.KeyChar)
            && e.KeyChar == ',')
        {
            e.Handled = true;
        }
        // only allow one decimal point
        if (e.KeyChar == '.'
            && (sender as TextBox).Text.IndexOf('.') > -1)
        {
            e.Handled = true;
        }
    }

然后创建一个小助手方法来解析文本框的值为decimal

    private decimal GetValueFromTextBox(string input)
    {
        input = System.Text.RegularExpressions.Regex.Replace(input, @"[,$%]", String.Empty);
        //Could use Try parse here for better handling
        decimal output = Convert.ToDecimal(input);
        return output;
    }

然后从你的TextBox_Leave事件中调用函数:

    private void textBox1_Leave(object sender, EventArgs e)
    {
        var value = GetValueFromTextBox(textBox1.Text);
        textBox1.Text = value.ToString("c");
    }

这将使用适当的逗号位置将值格式化为Currency格式,并且只强制执行一个小数点。再次不是最好的解决方案(使用一个MaskedTextBox),但它将工作为一个正常的TextBox控件

您可以使用NumericUpDown控件来避免任何手动验证数字

您可以使用MaskedTextbox

来限制文本框中允许的输入。

如果您更喜欢逻辑/手动测试,请添加如下内容:!textBox1.Text.Contains(',')

仅当文本框中没有逗号时才返回true。

编辑:实际上,我不确定是否新添加的逗号将包括在之前或之后的按键事件-如果它包括在内,那么你可能不得不使用计数代替:

if( ... && (textBox1.Text.Count(c => c == ',') <= 1) ) 
{
    ....
}

PS:我将重构这段代码,并将测试移到单独的方法中以保持整洁,所以主测试看起来像这样:

if(IsValidChar(e.KeyChar) && IsOnlyOneCommaProvided()){ 
    ...
}

您可以使用像['d]*,['d]*这样的正则表达式,这将确保它只匹配数字之间最多有一个逗号的约束。

更新:类似以下内容:

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    var newString = textBox1.Text += e.KeyChar;
    if(!Regex.IsMatch(newString, "['d]*,['d]*"))
        e.Handled = true;
    base.OnKeyPress(e);
}

我建议检查第三方控件。它们节省了大量的时间(也就是金钱)和头痛。DevExpress TextEdit控件做到了这一点……这是一个简单的选项,不需要任何时间来设置。我想其他所有的公司(Telerik, Infragistics等)也这么做。

javascript解决方案如何?

它的优点是与平台无关,并且在文本字段中照顾光标位置,而且不需要在服务器端进行处理,这总是很好。

一个缺点是,如果JS被禁用,另一个你必须"清理"的逗号值在服务器端提交时。总而言之,我认为这是一个更优雅的解决方案。

只需添加到您的文本框type='tel'属性,如:

<input type='tel' />

<script type="text/javascript">
    $(function () {
        $("[type='tel']").keydown(function (event) {
            var position = this.selectionStart;
            var $this = $(this);
            var val = $this.val();
            if (position == this.selectionEnd &&
                ((event.keyCode == 8 && val.charAt(position - 1) == "," && val.substr(0, position - 1).indexOf(".") == -1)
                || (event.keyCode == 46 && val.charAt(position) == "," && val.substr(0, position).indexOf(".") == -1))) {
                event.preventDefault();
                if (event.keyCode == 8) {
                    $this.val(val.substr(0, position - 2) + val.substr(position));
                    position = position - 2;
                } else {
                    $this.val(val.substr(0, position) + val.substr(position + 2));
                }
                $this.trigger('keyup', { position: position });
            } else {
                this.dispatchEvent(event);
            }
        });
                $("[type='tel']").keyup(function(event, args) {
                        if (event.which >= 37 && event.which <= 40) {
                                event.preventDefault();
                        }
                        var position = args ? args.position : this.selectionStart;
                        var $this = $(this);
                        var val = $this.val();
                        var parts =val.split(".");
                    var valOverDecimalPart = parts[0];
                        var commaCountBefore = valOverDecimalPart.match(/,/g) ? valOverDecimalPart.match(/,/g).length : 0;
                        var num = valOverDecimalPart.replace(/[^0-9]/g, '');
                        var result = parts.length == 1 ? num.replace(/('d)(?=('d{3})+(?!'d))/g, "$1,") : num.replace(/('d)(?=('d{3})+(?!'d))/g, "$1,") +"."+ parts[1].replace(/[^0-9.]/g,"");
                    $this.val(result);
                    var commaCountAfter = $this.val().match(/,/g) ? $this.val().match(/,/g).length : 0;
                        position = position + (commaCountAfter - commaCountBefore);
                        this.setSelectionRange(position, position);
                });
            });
    </script>