发短信到(int)-Textbox时,IDataErrorInfo的索引器不会引发

时间:2017-02-15 15:02:49

标签: c# validation mvvm idataerrorinfo

我无法检查用户是否将某些文本设置为绑定到整数值的文本框。如果用户设置数字,一切正常。如果是负数,则红色边框出现在文本框外部,并且“确定”按钮会变灰。如果他将文本设置到文本框中,文本框也是红色的,但是OK按钮不会变灰。

enter image description here

我收到了以下文本框和按钮

<TextBox Text="{Binding ObjectModel.Length, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" x:Name="textBox_Length" />

<Button x:Name="button_applyChanges" Content="Speichern" Command="{Binding ObjectModel.OkCommand}" />

我的模型如下:

public class ObjectModel : BaseModel
{
    [Required(AllowEmptyStrings = false, ErrorMessage = "{0} can't be empty.")]
    [Range(typeof(Decimal), "0", "100000000", ErrorMessage = "{0} must be a decimal/number between {1} and {2}.")]
    public int Length { get; set; }

    public RelayCommand OkCommand { get; private set; }

    protected override void InitCommands()
    {
        base.InitCommands();
        OkCommand = new RelayCommand(
            () =>
            {
                Trace.WriteLine("OK");
            },
            () => IsOk);
    }

    protected override void OnErrorsCollected()
    {
        base.OnErrorsCollected();
        OkCommand.RaiseCanExecuteChanged();
    }
}

在basemodel我包括IDataErrorInfo和INotifyPropertyChanged。我为indexer-call获得了以下方法,但是indexer-call没有在text-input上引发...

    public virtual string this[string columnName]
    {
        get
        {
            CollectErrors();
            return Errors.ContainsKey(columnName) ? Errors[columnName] : string.Empty;
        }
    }

    private void CollectErrors()
    {
        Errors.Clear();
        PropertyInfos.ForEach(
            prop =>
            {
                var currentValue = prop.GetValue(this);
                var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>();
                var maxLenAttr = prop.GetCustomAttribute<MaxLengthAttribute>();
                var numericAttr = prop.GetCustomAttribute<RangeAttribute>();

                if (requiredAttr != null)
                    if (string.IsNullOrEmpty(currentValue?.ToString() ?? string.Empty))
                        Errors.Add(prop.Name, requiredAttr.ErrorMessage);

                if (maxLenAttr != null)
                    if ((currentValue?.ToString() ?? string.Empty).Length > maxLenAttr.Length)
                        Errors.Add(prop.Name, maxLenAttr.ErrorMessage);

                if (numericAttr != null)
                {
                    var result = 0;
                    var resultBool = Int32.TryParse(currentValue.ToString(), out result);

                        if(result <= 0 || !resultBool)
                            Errors.Add(prop.Name, numericAttr.ErrorMessage);
                }
                // further attributes
            });
        // we have to this because the Dictionary does not implement INotifyPropertyChanged            
        OnPropertyChanged(nameof(HasErrors));
        OnPropertyChanged(nameof(IsOk));
        // commands do not recognize property changes automatically
        OnErrorsCollected();
    }

当用户将文本放入文本框时,我希望按钮变灰。

1 个答案:

答案 0 :(得分:0)

所以,我终于得到了解决方案......我将长度类型更改为字符串并使用正则表达式解决了它。

ObjectModel:

    [RegularExpression("([1-9][0-9]*)", ErrorMessage = "Must be a positive number")]
    public string Length { get; set; }

New CollectErrors() - basemodel的方法:

    private void CollectErrors()
    {
        Errors.Clear();
        PropertyInfos.ForEach(
            prop =>
            {
                var currentValue = prop.GetValue(this);
                var requiredAttr = prop.GetCustomAttribute<RequiredAttribute>();
                var maxLenAttr = prop.GetCustomAttribute<MaxLengthAttribute>();
                var regexAttr = prop.GetCustomAttribute<RegularExpressionAttribute>();

                if (requiredAttr != null)
                    if (string.IsNullOrEmpty(currentValue?.ToString() ?? string.Empty))
                        Errors.Add(prop.Name, requiredAttr.ErrorMessage);

                if (maxLenAttr != null)
                    if ((currentValue?.ToString() ?? string.Empty).Length > maxLenAttr.Length)
                        Errors.Add(prop.Name, maxLenAttr.ErrorMessage);

                if (regexAttr != null)
                    if (!regexAttr.IsValid((currentValue?.ToString() ?? string.Empty)))
                        Errors.Add(prop.Name, regexAttr.ErrorMessage);
            });
        OnPropertyChanged(nameof(HasErrors));
        OnPropertyChanged(nameof(IsOk));
        OnErrorsCollected();
    }