我在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);
}
上面的代码效果非常好,但是我可以添加2个逗号,例如" 100 ,, 00" 。我怎样才能让用户添加" 100, 00" 或" 100,000,000" 以1个逗号作为货币格式?
任何帮助将不胜感激。
感谢。
答案 0 :(得分:5)
不能直接回答您的实际问题,但绝对是您应该考虑的建议:使用MaskedTextBox
,而不是TextBox
。
MaskedTextBox
具有Mask
属性,可用作文本值的模式。在您的情况下,适当的掩码可能是#,###.##
。请注意,根据您的程序集在小数分隔符上的文化,可能不是逗号。不过,您仍然可以将其转换为数值,这无论如何都是您想要的。
<强>更新强>
作为一个额外的建议,像devexpress这样的第三方供应商确实提供了更高级的掩码输入控件,可以使用传统掩码和基于正则表达式的验证器。如果你能负担得起这笔钱,可能需要考虑一下。
答案 1 :(得分:1)
您可以使用NumericUpDown控件来避免手动验证数字。
答案 2 :(得分:1)
正如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;
}
}
然后创建一个小帮助方法来将TextBox的值解析为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");
}
这将使用适当的逗号位置格式化货币格式的值,同时仅强制执行一个小数点。再次不是最佳解决方案(使用MaskedTextBox),但它适用于普通的TextBox
控件。
答案 3 :(得分:0)
您可以使用MaskedTextbox
,
如果您希望逻辑/手动测试,请添加以下内容:!textBox1.Text.Contains(',')
。
只有在文本框中没有逗号时才会返回true。
编辑:实际上,我不确定在按键事件之前或之后是否会包含新添加的逗号 - 如果 包含在内,那么您可能不得不使用计数:< / p>
if( ... && (textBox1.Text.Count(c => c == ',') <= 1) )
{
....
}
PS:我会重构此代码并将测试移到单独的清洁方法中,因此主要测试看起来像这样:
if(IsValidChar(e.KeyChar) && IsOnlyOneCommaProvided()){
...
}
答案 4 :(得分:0)
你可以使用像 [\ 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);
}
答案 5 :(得分:0)
我建议您查看第三方控件。他们节省了大量的时间(这是金钱)和头痛。 DevExpress TextEdit控件执行此操作...这是一个简单的选项,完全没有时间设置。我假设所有其他人(Telerik,Infragistics等)也这样做。
答案 6 :(得分:-1)
javascript解决方案怎么样?
它受益于独立于平台,并负责文本字段中的光标位置,加上服务器端的处理总是很好。
一个缺点是如果JS被禁用,另一个你必须清理&#39;提交时服务器端的逗号值。总而言之,我认为这是更优雅的解决方案。
只需添加到您的文本框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>