0

我正在使用INotifyDataErrorInfo,这个实现:https ://kmatyaszek.github.io/wpf-validation/2019/03/13/wpf-validation-using-inotifydataerrorinfo.html

万一链接失效的代码:

public class MainViewModel : BindableBase, INotifyDataErrorInfo
{
    private string _userName;
    private readonly Dictionary<string, List<string>> _errorsByPropertyName = new Dictionary<string, List<string>>();

    public MainViewModel()
    {
        UserName = null;
    }

    public string UserName
    {
        get => _userName;
        set
        {
            _userName = value;
            ValidateUserName();
            RaisePropertyChanged();
        }
    }

    public bool HasErrors => _errorsByPropertyName.Any();

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
        return _errorsByPropertyName.ContainsKey(propertyName) ?
            _errorsByPropertyName[propertyName] : null;
    }

    private void OnErrorsChanged(string propertyName)
    {
        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
    }

    private void ValidateUserName()
    {
        ClearErrors(nameof(UserName));
        if (string.IsNullOrWhiteSpace(UserName))
            AddError(nameof(UserName), "Username cannot be empty.");
        if (string.Equals(UserName, "Admin", StringComparison.OrdinalIgnoreCase))
            AddError(nameof(UserName), "Admin is not valid username.");
        if (UserName == null || UserName?.Length <= 5)
            AddError(nameof(UserName), "Username must be at least 6 characters long.");
    }

    private void AddError(string propertyName, string error)
    {
        if (!_errorsByPropertyName.ContainsKey(propertyName))
            _errorsByPropertyName[propertyName] = new List<string>();

        if (!_errorsByPropertyName[propertyName].Contains(error))
        {
            _errorsByPropertyName[propertyName].Add(error);
            OnErrorsChanged(propertyName);
        }
    }

    private void ClearErrors(string propertyName)
    {
        if (_errorsByPropertyName.ContainsKey(propertyName))
        {
            _errorsByPropertyName.Remove(propertyName);
            OnErrorsChanged(propertyName);
        }
    }
}

它工作得很好,但现在我想验证整数值,而不是字符串。基本上用户应该不能输入除 之外的任何内容int,否则应用程序将崩溃。但我不知道我ValidateIntegerValue()可以写什么方法,因为我无法检查 if intis int,因为在后端它总是整数。

4

1 回答 1

0

int属性只能设置为int. 时期。验证视图或视图中的控件是否不尝试将其设置为任何其他值不是视图模型的责任,因为这总是会失败。视图模型只是公开属性,视图有责任设置它。

所以首先要了解的是,这种验证应该发生在视图或控件中。绑定到string属性然后转换视图模型中的值是一个坏主意。

你可以做的是创建一个自定义ValidationRule

public class StringToIntValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        int i;
        if (int.TryParse(value.ToString(), out i))
            return new ValidationResult(true, null);

        return new ValidationResult(false, "Please enter a valid integer value.");
    }
}

...您与绑定相关联:

<TextBox>
    <TextBox.Text>
        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:StringToIntValidationRule ValidationStep="RawProposedValue"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

请参阅博客文章了解更多信息。

如果您想防止用户在 中输入无效值TextBox,您可以处理该PreviewTextInput事件或创建自定义控件。同样,这与视图模型无关。

于 2020-05-22T14:24:21.420 回答