WPF文本框正则表达式需求:仅允许一个小数点及有效数字输入
解决WPF TextBox的数字输入正则验证问题
嘿,这个WPF TextBox的输入限制需求我太懂了!你要的是允许纯数字、带小数点且后面有数字,甚至输入到一半末尾留着小数点的情况,同时还得禁止多个小数点对吧?我给你量身定制个正则表达式,再告诉你怎么在WPF里用起来。
符合需求的正则表达式
直接上能用的:
^\d+(\.\d*)?$
正则拆解(帮你理解为什么好用)
^和$:确保匹配整个输入内容,不会漏掉首尾的非法字符\d+:强制开头至少有一个数字,这样就杜绝了纯小数点(比如.)的非法输入(\.\d*)?:这是个可选的分组:\.:匹配唯一的一个小数点(保证不会出现多个)\d*:允许小数点后面跟0个或多个数字——这就支持了两种情况:末尾留着小数点(比如1.),或者小数点后有数字(比如1.2、33.0)?:表示这个分组可以完全不出现,也就是支持纯数字输入(比如1、33)
这个正则完美覆盖你列出的所有合法案例:1、1.2、1.、33.0、33、55.23、55.6,同时自动拦截多个小数点、纯小数点这类非法输入。
在WPF里的两种实现方式
方式1:用ValidationRule做绑定验证
适合MVVM模式,通过数据绑定的验证规则来提示用户:
- 先写一个自定义验证规则类:
public class DecimalInputValidationRule : ValidationRule { private readonly Regex _validInputRegex = new Regex(@"^\d+(\.\d*)?$"); public override ValidationResult Validate(object value, CultureInfo cultureInfo) { var inputText = value?.ToString() ?? string.Empty; // 如果你允许空输入,就返回Valid;否则改成Invalid if (string.IsNullOrWhiteSpace(inputText)) return ValidationResult.ValidResult; return _validInputRegex.IsMatch(inputText) ? ValidationResult.ValidResult : new ValidationResult(false, "请输入有效的格式:纯数字、带小数点的数字或末尾为小数点的数字"); } }
- 在XAML里绑定的时候应用这个规则:
<TextBox> <TextBox.Text> <Binding Path="YourViewModelProperty" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:DecimalInputValidationRule ValidationStep="RawProposedValue"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
方式2:用PreviewTextInput实时拦截非法输入
如果你想在用户输入的时候就直接阻止非法字符(不让它们出现在TextBox里),可以用事件处理:
private void NumberTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { if (sender is not TextBox textBox) return; // 模拟输入后的完整文本 var proposedText = textBox.Text.Insert(textBox.CaretIndex, e.Text); var regex = new Regex(@"^\d+(\.\d*)?$"); // 如果不符合正则,就阻止输入 e.Handled = !regex.IsMatch(proposedText); }
别忘了还要处理粘贴的情况,不然用户粘贴非法内容会绕过上面的拦截:
private void NumberTextBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (sender is not TextBox textBox) return; if (e.DataObject.GetDataPresent(typeof(string))) { var pastedText = (string)e.DataObject.GetData(typeof(string)); var proposedText = textBox.Text.Insert(textBox.CaretIndex, pastedText); var regex = new Regex(@"^\d+(\.\d*)?$"); if (!regex.IsMatch(proposedText)) e.CancelCommand(); } else { e.CancelCommand(); } }
额外说明
如果你的需求需要支持负数,只要把正则改成 ^-?\d+(\.\d*)?$ 就行,开头的-?表示允许可选的负号。
内容的提问来源于stack exchange,提问作者Geeth
相关产品推荐
相关产品推荐

