AutoCompleteBox validation broken? · AvaloniaUI/Avalonia · Discussion #17459 (original) (raw)

Avalonia 11.2.0 running on Windows desktop

Question: Is there something that I am doing wrong here, or is validation broken?

Any help would be appreciated.

I am having issues with data validation using the AutoCompleteBox. The behavior I am seeing is that if the bound value starts out with a validation error, the AutoCompleteBox will display the validation error. As long as the value is in error, the AutoCompleteBox will display the correct validation error. For example, I change between a required validator and a minimum length validator. Once all validation errors are cleared, the AutoCompleteBox will not display any validation errors.

I have reproduced this behavior with the BindingDemo included in the Avalonia source. That demo uses all three types of data validation, Exceptions, INotifyDataErrorInfo and DataAnnotations. I get the above behavior using INotifyDataErrorInfo and DataAnnotations. Using the Exceptions validation plugin, AutoCompleteBox is not displaying any validation errors.

Xaml for the AutoCompleteBox for all validation pluggins:

<AutoCompleteBox Watermark="Auto-complete" Text="{Binding Item}" ItemsSource="{Binding ItemValues}"/>

DataAnnotations view model properties:

        [Required]
        [MinLength(2)]
        public string Item { get; set; }

        public ObservableCollection<string> ItemValues { get; set; } = new ObservableCollection<string>(["one", "two", "three"]);

INotifyDataErrorInfo view model properties:

        private string _item;
        private string _itemError;
        public string Item
        {
            get { return _item; }
            set { this.RaiseAndSetIfChanged(ref _item, value); }
        }

        public ObservableCollection<string> ItemValues { get; set; } = new ObservableCollection<string>(["one", "two", "three"]);


        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

        public IEnumerable GetErrors(string propertyName)
        {
            switch (propertyName)
            {
                case nameof(Value):
                    return new[] { _valueError };
                case nameof(Item):
                    return new[] { _itemError };
                default:
                    return null;
            }
        }

        private void UpdateErrors()
        {
            if (string.IsNullOrEmpty(Item))
            {
                _itemError = "Item required.";
                ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Item)));
            }
            else if (Item.Length < 2)
            {
                _itemError = "Item length must be at least 2.";
                ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Item)));
            }
            else
            {
                _itemError = null;
                ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Item)));
            }
        }
    }

Exception view model properties:

        private string _item;
        public string Item
        {
            get { return _item; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new DataValidationException("Item required.");

                    //throw new ArgumentOutOfRangeException(nameof(value), "Item required.");
                }
                else if (value.Length < 2)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "Item length must be at least 2.");
                }
                else
                {
                    this.RaiseAndSetIfChanged(ref _item, value);
                }
            }
        }

        public ObservableCollection<string> ItemValues { get; set; } = new ObservableCollection<string>(["one", "two", "three"]);

With validation errors displayed:

image

With validation errors missing:

image