带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逗号作为货币格式?
任何帮助都将不胜感激。
谢谢。
不是对你实际问题的直接回答,但绝对是你应该考虑的建议:使用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>