You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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模式,通过数据绑定的验证规则来提示用户:

  1. 先写一个自定义验证规则类:
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, "请输入有效的格式:纯数字、带小数点的数字或末尾为小数点的数字");
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:13:54