首页 > 解决方案 > float.NaN 的 DataAnnotations 属性

问题描述

DataAnnotations用于验证我的ViewModel (WPF),因此如果用户键入的不是浮点数并且值超出范围,我可以控制某些按钮的启用状态。

    [Range(0, float.MaxValue, ErrorMessage = "StepSize must be more than 0")]
            public float StepSize
            {
                get { return model.StepSize; }
                set
                {                   
                    model.StepSize = value;
                    RaisePropertyChangedAndRevalidate(nameof(StepSize));
                }
            }

private void RaisePropertyChangedAndRevalidate(string propertyName)
        {
            RaisePropertyChanged(propertyName);
            if (_fieldBindingErrors == 0)
            {
                RaisePropertyChanged(nameof(IsValid));
            }
        }


        private int _fieldBindingErrors = 0;
        public ICommand RegisterFieldBindingErrors
        {
            get
            {
                return new RelayCommand<ValidationErrorEventArgs>(e =>
                {
                    if (e.Action == ValidationErrorEventAction.Added)
                    {
                        _fieldBindingErrors++;
                    }
                    else
                    {
                        _fieldBindingErrors--;
                    }
                    RaisePropertyChanged(nameof(IsValid));
                });
            }
        }

        public bool IsValid
        {
            get
            {
                bool valid = Validator.TryValidateObject(this,
                                   new ValidationContext(this, null, null),
                                   new List<System.ComponentModel.DataAnnotations.ValidationResult>())
                                   && _fieldBindingErrors == 0;

                return valid;
            }
        }

问题是,当我将 textbox.Text 字符串转换为浮点数时,我必须将值设置为无效的值(在不使用 Range 属性时也应该适用于一般情况)。所以我将值设置为float.NaN。问题是 NaN 似乎是一个有效的浮点数,它甚至通过了上面的 Range 验证。

是否有我可以用来验证该值不是 NaN 的属性?

标签: c#.netwpfvalidationdata-annotations

解决方案


找到了一个解决方案,我创建了一个自定义验证规则并将其应用于 XAML。

类 StepSizeValidationRule : ValidationRule { private int _min; 私人int _max;

    public StepSizeValidationRule()
    {
    }

    public int Min
    {
        get { return _min; }
        set { _min = value; }
    }

    public int Max
    {
        get { return _max; }
        set { _max = value; }
    }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        float stepSize = 0;

        try
        {
            if (!float.TryParse(value.ToString(), out stepSize))
            {
                return new ValidationResult(false, "Not a float");
            }

        }
        catch (Exception e)
        {
            return new ValidationResult(false, "Not a float " + e.Message);
        }

        if (float.IsNaN(stepSize))
        {
            return new ValidationResult(false, "Not a float ");
        }

        if ((stepSize < Min) || (stepSize > Max))
        {
            return new ValidationResult(false,
              "Please enter a stepSize in the range: " + Min + " - " + Max + ".");
        }
        else
        {
            return new ValidationResult(true, null);
        }
    }
}

推荐阅读