WPF验证规则防止文本框中的小数输入? [英] WPF validation rule preventing decimal entry in textbox?

查看:25
本文介绍了WPF验证规则防止文本框中的小数输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 XAML 中定义了一个 WPF 文本框,如下所示:

I have a WPF textbox defined in XAML like this:

<Window.Resources>        
    <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<TextBox x:Name="upperLeftCornerLatitudeTextBox" Style="{StaticResource textBoxInError}">
    <TextBox.Text>
        <Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:LatitudeValidationRule ValidationStep="RawProposedValue"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

如您所见,我的文本框绑定到名为 UpperLeftCornerLatitude 的业务对象上的小数属性,如下所示:

As you can see, my textbox is bound to a decimal property on my business object called UpperLeftCornerLatitude which looks like this:

private decimal _upperLeftCornerLongitude;
public decimal UpperLeftCornerLatitude
{
    get { return _upperLeftCornerLongitude; }
    set
    {
        if (_upperLeftCornerLongitude == value)
        {
            return;
        }

        _upperLeftCornerLongitude = value;
        OnPropertyChanged(new PropertyChangedEventArgs("UpperLeftCornerLatitude"));
    }
}

我的用户将在此文本框中输入纬度值,为了验证该条目,我创建了如下所示的验证规则:

My user will be entering a latitude value into this textbox and in order to validate that entry, I've created a validation rule that looks like this:

public class LatitudeValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        decimal latitude;

        if (decimal.TryParse(value.ToString(), out latitude))
        {
            if ((latitude < -90) || (latitude > 90))
            {
                return new ValidationResult(false, "Latitude values must be between -90.0 and 90.0.");
            }
        }
        else
        {
            return new ValidationResult(false, "Latitude values must be between -90.0 and 90.0.");
        }

        return new ValidationResult(true, null);
    }
}

我的文本框最初是空的,我在验证规则的开头设置了一个断点.我在文本框中输入 1,当我的调试器在验证规则内中断时,我可以看到 value = "1".到现在为止还挺好.现在我继续运行并在文本框中输入一个小数点(所以我们现在应该有1.").再次,调试器打破了验证规则,正如预期的那样,value = "1.".如果我单步执行验证规则代码,我会看到它通过了纬度值检查并返回以下内容:

My textbox initially starts off empty and I have a breakpoint set at the beginning of my validation rule. I enter 1 in the textbox and when my debugger breaks inside of the validation rule, I can see that value = "1". So far so good. Now I continue running and enter a decimal point in the textbox (so we should have "1." now). Again, the debugger breaks inside of the validation rule and, as expected, value = "1.". If I step through the validation rule code, I see that it passes the latitude value check and returns the following:

new ValidationRule(true, null);

但是,一旦验证规则返回并进入下一行代码,我发现自己位于 UpperLeftCornerLatitude 属性设置器的第一行.将鼠标悬停在此处的 value 上表明它是1"而不是1"的值.正如我所料.所以很自然地,当我继续运行我的代码时,我最终会回到文本框中,盯着值1"而不是1.".如果我删除所有断点,效果是我似乎无法在文本框中输入小数点.是否有一些明显的我在这里遗漏的东西导致我的设置器最终得到一个值1",即使我输入了1".在文本框中?非常感谢!

However, as soon as the validation rule returns and I step into the next line of code, I find myself on the first line of my UpperLeftCornerLatitude property setter. Mousing over value here reveals that it's a value of "1" instead of "1." as I would expect. So naturally when I continue running my code, I end up back in the textbox staring at a value of "1" instead of "1.". If I remove all of the breakpoints, the effect is that I can't seem to enter a decimal point in the textbox. Is there something obvious that I'm missing here that's causing my setter to end up with a value of "1" even though I have entered "1." in the textbox? Thanks very much!

推荐答案

这里有几个方法可以解决这个问题

Here are a few ways to fix this problem

A.为您的绑定指定 LostFocus(默认文本框)

A. Specify LostFocus (textbox default) for your binding

<Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="LostFocus">
</Binding>

B.为绑定指定一个延迟,这将允许您在一段时间内输入小数

B. Specify a Delay for the binding that will allow for some time for you to type the decimal

<Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" Delay="1000">
</Binding>

C.把decimal改成string自己解析

D.编写一个 ValueConverter 来覆盖默认的转换过程

D. Write a ValueConverter to override the default conversion process

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

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ...
    }
}

这篇关于WPF验证规则防止文本框中的小数输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆