C# 文本框赢得';I don’我不允许输入小数

C# 文本框赢得';I don’我不允许输入小数,c#,xaml,C#,Xaml,我可以在文本框中输入数字,但它不允许我输入十进制值。请问这是为什么 <TextBox Text="{Binding SebAmountPer, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="2" TextWrapping="Wrap"/> public decimal? SebAmountPer { get { return _seb.SEBA

我可以在文本框中输入数字,但它不允许我输入十进制值。请问这是为什么

<TextBox Text="{Binding SebAmountPer, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="2" TextWrapping="Wrap"/>

public decimal? SebAmountPer
{
    get
    {
        return _seb.SEBAmountPer;
    }
    set
    {
        _seb.SEBAmountPer = value; 
        OnPropertyChanged("SebAmountPer");
        OnPropertyChanged("SebTotal");
    }
}

公共小数?塞巴莫特
{
得到
{
返回seb.SEBAMONTPER;
}
设置
{
_seb.SEBAmountPer=数值;
不动产变更(“SEBAMONTPER”);
不动产变更(“SebTotal”);
}
}

您有一个与数字数据类型的双向绑定。触发器是属性更改,这意味着在每次按键之后。首先尝试绑定到字符串或更改更新触发器


你输入“2”,他将绑定更新为2.0并将其转换回来,然后偷走你的点;)

这种行为是完全正确的,因为点-“.”作为数字没有任何意义

以下是有效数字:1,3.3,23.124,1,23.0

以下是无效数字:-->(我指的是圆点),.12

因此,如果您不想这样做,请使用以下代码

private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
   Regex regex = new Regex("^[.][0-9]+$|^[0-9]*[.]{0,1}[0-9]*$");
   e.Handled = !regex.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart,e.Text));
}
一种廉价的解决方法(如果您仍然希望保留内置的验证并将其绑定到可为null的属性),就是在绑定中添加一个小的
延迟。这允许您实际输入一个“小数点”,并在“延迟”后绑定,然后将值计算为正确值

例如:

  <TextBox Text="{Binding SebAmountPer, UpdateSourceTrigger=PropertyChanged, TargetNullValue='', Delay=350}" Height="75" Width="300" TextWrapping="Wrap"/>

如果您有.NET 4.5或更新版本,请添加到
App.xaml.cs
文件
System.Windows.FrameworkCompatibilityPreferences.keeptextboxdisplay synchronized with textproperty=false如下所示:

public partial class App : Application
{
    public App()
    {
        System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
    }
}

这是绑定值验证问题,您只需要设置

UpdateSourceTrigger=LostFocus
在文本框中,使用123 456 789 0的答案:

private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
   Regex regex = new Regex("^[.][0-9]+$|^[0-9]*[.]{0,1}[0-9]*$");
   e.Handled = !regex.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart,e.Text));
}

我用一个值转换器来解决这个问题

public class DecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            string s_value = value.ToString();
            if (s_value.EndsWith("."))
            {
                return s_value.Replace(".", ".0");
            }
            else if (s_value.Contains(".") && s_value.EndsWith("0"))
            {
                return s_value.Substring(0, s_value.Length - 1);
            }
            return value;
        }
        return null;
    }
}



<TextBox>
    <Binding Path="UnitCost" UpdateSourceTrigger="PropertyChanged" Converter="{StaticResource decimalConverter}"/>
</TextBox>
公共类小数转换器:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
返回值;
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
if(值!=null)
{
字符串s_value=value.ToString();
如果(s_值以“.”结尾)
{
返回s_值。替换(“.”,“.0”);
}
如果(s_value.Contains(“.”)和s_value.EndsWith(“.0”))
{
返回s_值.Substring(0,s_值.Length-1);
}
返回值;
}
返回null;
}
}

您可以从
UpdateSourceTrigger=PropertyChanged
更改为
UpdateSourceTrigger=LostFocus
。它将允许您插入点/逗号,并在光标框更改时验证

试试这个。 我换了房间

UpdateSourceTrigger=PropertyChanged 

UpdateSourceTrigger=LostFocus

你试过点和逗号吗?是的!除了数字和字母外,没有其他功能,但我只想要数字。因此,我可以手动将光标放在我想要的小数点位置,并将其输入。但是如果我按常规方式键入它,它就不适用了。如果键入10,然后将光标放在1和0之间,然后键入十进制分隔符,会发生什么情况?这很好。计算仍在进行中,并考虑了小数点。因此,它实际上显示1.0与您的方法非常相似,但我想保留我的MVVM为什么
.12
是无效数字?您可以使用
行为来封装它。你也不希望它出现在
ViewModel
层,因为它是为
UI
@Magnus做的。我没有说我认为它无效,但
TextBox
控件认为它无效。伙计,你仍然需要设置UpdateSourceTrigger=LostFocus。这就解决了OP的问题。此解决方案简单且符合逻辑。比选择的答案要好得多,延迟350,如果我在350之后输入怎么办?这很便宜,但是如果用户在350之后输入一个值怎么办?
UpdateSourceTrigger=LostFocus

<TextBox Text="{Binding SebAmountPer, UpdateSourceTrigger=LostFocus}" Grid.Column="1" Grid.Row="2" TextWrapping="Wrap"/>