TextBox money format with 1 comma
我在 c# winforms 中有一个文本框。
1 2 3 4 5 6 7 8 9 10 | 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); } |
上面的代码效果很好,但是我可以添加 2 个逗号,例如"100,,00"。我怎样才能让用户添加"100,00"或"100,000,000"和 1 个逗号作为货币格式?
任何帮助将不胜感激。
谢谢。
不是对您的实际问题的直接回答,但绝对是您应该考虑的建议:为此使用
更新:
作为附加建议,一些 3rd 方 vendor(如 devexpress)确实提供了具有更高级掩码输入的控件,这些掩码输入可以使用传统掩码以及基于正则表达式的验证器。如果你能负担得起这笔钱,它可能是值得研究的。
正如 Crono 在另一个答案中所说,a
这有点被破解了,但应该可以实现你想要的:
首先创建不允许逗号输入的事件处理程序,只允许一个小数点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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; } } |
然后创建一个小助手方法来将 TextBox 的值解析为
1 2 3 4 5 6 7 | 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; } |
然后从你的
1 2 3 4 5 6 | private void textBox1_Leave(object sender, EventArgs e) { var value = GetValueFromTextBox(textBox1.Text); textBox1.Text = value.ToString("c"); } |
这会将值格式化为货币格式,并使用适当的逗号放置,也只强制保留一位小数。再次不是最好的解决方案(使用 MaskedTextBox),但它适用于普通
您可以使用 NumericUpDown 控件来避免对数字进行任何手动验证。
我建议检查 3rd 方控件。他们节省了大量时间(这是金钱)和头痛。 DevExpress TextEdit 控件执行此操作……这是一个简单的选项,完全不需要时间来设置。我假设所有其他人(Telerik、Infragistics 等)也这样做。
你可以使用像 [\\\\d]*,[\\\\d]* 这样的正则表达式来确保它只匹配数字之间最多有一个逗号的约束。
更新:大致如下:
1 2 3 4 5 6 7 8 | 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); } |
您可以通过使用
来限制文本框中允许的输入
如果您更喜欢逻辑/手动测试,请添加以下内容:
只有当文本框中还没有逗号时才会返回 true。
编辑:实际上,我不确定新添加的逗号是否会包含在按键事件之前或之后 - 如果包含,那么您可能必须使用 count 代替:
1 2 3 4 | if( ... && (textBox1.Text.Count(c => c == ',') <= 1) ) { .... } |
PS:我会重构这段代码并将测试移到单独的方法中以保持清洁,所以主要测试看起来像这样:
1 2 3 | if(IsValidChar(e.KeyChar) && IsOnlyOneCommaProvided()){ ... } |
javascript解决方案怎么样?
它受益于独立于平台,并负责文本字段中的光标位置,加上服务器端没有处理,这总是很好。
一个缺点是如果 JS 被禁用,另一个你必须在提交时在服务器端"清理"逗号值。我认为它是更优雅的解决方案。
只需添加到您的文本框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <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); }); }); |