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

为何无法在WPF TextBox中输入小数?如何解决?

WPF TextBox绑定decimal?无法输入小数点的问题及解决方法

问题重现

ViewModel代码

public class ViewModelData : INotifyPropertyChanged
{
    private decimal? myValue;
    public decimal? MyValue
    {
        get { return myValue; }
        set
        {
            myValue = value;
            OnPropertyChanged(nameof(MyValue));
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML代码

<TextBox 
    Name="MyValueBox" 
    Text="{Binding MyValue, UpdateSourceTrigger=PropertyChanged}" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Top" 
    Width="112" 
    Margin="0,96,0,0"/>

问题现象:输入1.0时,先输入1后无法直接输入小数点;但先输入其他内容(如text1.0)或在已输入的数字中间插入小数点(如先输10再在中间加.变成1.0)则可以正常工作。

原因解析

核心问题在于UpdateSourceTrigger=PropertyChanged的行为:每输入一个字符就会触发数据源更新。当输入1.时,WPF默认的类型转换器会尝试将字符串"1."转换为decimal?类型,但该字符串不符合有效的decimal格式,转换失败,导致数据源不更新,TextBox会自动回退到之前的有效值"1",小数点因此被清除。而在数字中间插入小数点得到"1.0"时,字符串是有效的decimal格式,转换成功,所以能保留输入内容。

解决方案

方案1:调整UpdateSourceTrigger触发时机

将绑定的UpdateSourceTrigger改为LostFocus,这样仅当TextBox失去焦点时才更新数据源,输入过程中不会触发类型转换,自然可以正常输入小数点:

<TextBox 
    Name="MyValueBox" 
    Text="{Binding MyValue, UpdateSourceTrigger=LostFocus}" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Top" 
    Width="112" 
    Margin="0,96,0,0"/>

方案2:实现自定义值转换器

创建自定义转换器,处理输入过程中的中间状态(如单个小数点),避免转换失败导致的回退:

public class DecimalNullableConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is decimal? dec && dec.HasValue 
            ? dec.ToString(culture) 
            : string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var input = value as string;
        if (string.IsNullOrWhiteSpace(input))
            return null;
            
        // 允许输入单个小数点,可根据需求返回0或null
        if (input == ".")
            return decimal.Zero;
            
        if (decimal.TryParse(input, NumberStyles.Any, culture, out var result))
            return result;
            
        // 转换失败时返回Binding.DoNothing,避免TextBox回退到旧值
        return Binding.DoNothing;
    }
}

在XAML中引用转换器:

<Window.Resources>
    <local:DecimalNullableConverter x:Key="DecimalNullableConverter"/>
</Window.Resources>

<TextBox 
    Name="MyValueBox" 
    Text="{Binding MyValue, Converter={StaticResource DecimalNullableConverter}, UpdateSourceTrigger=PropertyChanged}" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Top" 
    Width="112" 
    Margin="0,96,0,0"/>

方案3:使用掩码输入控件

借助WPF Toolkit或第三方库中的MaskedTextBox,设置合适的掩码(如0.00)来规范输入格式,从根源避免无效输入的转换问题。

内容的提问来源于stack exchange,提问作者markzzz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:32:06