WPF ValidationRule 删除小数点

WPF ValidationRule Dropping Decimal Point

我有以下 XAML:

            <TextBox Name="LevyWageLimitFormulaID_TextBox"
                     Width="150"
                     HorizontalAlignment="Center"
                     Grid.Row="4" Grid.Column="1">
                <TextBox.Text>
                    <Binding Path="SelectedStateRule.LevyRule.WageLimitFormulaID" 
                             UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <vm:NumericValidator ValidatesOnTargetUpdated="True" />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

验证器定义如下:

/// <summary>
/// Numeric Validator to make sure value is numeric
/// </summary>
public class NumericValidator : ValidationRule
{
    /// <summary>
    /// Validate field is blank or contains only numbers
    /// </summary>
    /// <param name="value"></param>
    /// <param name="cultureInfo"></param>
    /// <returns></returns>
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        Decimal _number;
        if (!Decimal.TryParse((value as string), out _number) && !String.IsNullOrEmpty(value as string))
        {
            return new ValidationResult(false, "Value must be numeric");
        }

        return ValidationResult.ValidResult;
    }
}

在我尝试输入十进制数之前,这一切正常。如果我在文本框中输入 '10.' 小数点被删除(用户永远不会看到小数点出现在文本框中)。如果我输入 '100' 然后手动移动光标并添加一个小数点以使值 '10.0' 验证有效并且小数点保留。

我知道这是由 Decimal.TryParseout _number 部分以及 属性 更改后立即执行的验证引起的(这是要求之一),但是有没有办法修复此方法,以便我可以键入 '10.' 并将小数点保留在文本框中?

这不是由您的 ValidationRule 引起的。如果您暂时删除 ValidationRule,您将遇到相同的行为。

问题是 decimal 源 属性 不能 设置为 decimal 值和“10”以外的值。确实不是有效的 decimal 值。

你可以做的是绑定到包装器 string 属性 来设置 decimal 属性:

//add this wrapper property to your class:
private string _wrapper;
public string Wrapper
{
    get { return _wrapper; }
    set
    {
        _wrapper = value;
        decimal d;
        if (Decimal.TryParse(_wrapper, out d))
            WageLimitFormulaID = d;
    }
}

private decimal _wageLimitFormulaID;
public decimal WageLimitFormulaID
{
    get { return _wageLimitFormulaID; }
    set { _wageLimitFormulaID = value; }
}

<TextBox Name="LevyWageLimitFormulaID_TextBox"
                     Width="150"
                     HorizontalAlignment="Center"
                     Grid.Row="4" Grid.Column="1">
    <TextBox.Text>
        <Binding Path="SelectedStateRule.LevyRule.Wrapper" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <vm:NumericValidator ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>