WPF - User input validation using Fody Validar

1.2k views Asked by At

enter image description here

I'm trying to validate user input as in above image. I'm using Fody Validor library and following the instruction here.

I can see the validation is taking place, but the TextBox borders are not turning into red color.

I have Googled and I was unable to get information on this. Could anyone provide me with a working code example?

UPDATE

Fody ValidationTemplate (Data Annotation Validation)

public class ValidationTemplate :IDataErrorInfo
    {

        INotifyPropertyChanged target;
        ValidationContext validationContext;
        List<ValidationResult> validationResults;

        public ValidationTemplate(INotifyPropertyChanged target)
        {
            this.target = target;
            validationContext = new ValidationContext(target, null, null);
            validationResults = new List<ValidationResult>();
            Validator.TryValidateObject(target, validationContext, validationResults, true);
            target.PropertyChanged += Validate;
        }

        void Validate(object sender, PropertyChangedEventArgs e)
        {
            validationResults.Clear();
            Validator.TryValidateObject(target, validationContext, validationResults, true);
            var hashSet = new HashSet<string>(validationResults.SelectMany(x => x.MemberNames));
            foreach (var error in hashSet)
            {
                OnValidate(error);
            }
        }


        private HashSet<string> _errors = new HashSet<string>();
        public string this[string columnName]
        {
            get
            {
                return OnValidate(columnName);
            }
        }

        protected virtual string OnValidate(string propertyName)
        {
            string error = string.Empty;

            try
            {
                if (string.IsNullOrEmpty(propertyName))
                    throw new ArgumentException("Invalid property name", propertyName);

                var value = this.GetType().GetProperty(propertyName).GetValue(this, null);
                var results = new List<ValidationResult>(1);
                var context = new ValidationContext(this, null, null) { MemberName = propertyName };
                var result = Validator.TryValidateProperty(value, context, results);
                if (!result)
                {
                    var validationResult = results.First();
                    error = validationResult.ErrorMessage;
                    _errors.Add(propertyName);
                }
                else
                {
                    _errors.Remove(propertyName);
                }
            }
            catch (Exception) { }

            return error;
        }

        public bool HasErrors
        {
            get { return _errors.Count > 0; }
        }

        public string Error { get; set; }
    }

Model class to be validated:

public class Movie :  INotifyPropertyChanged
    {
        IDataErrorInfo validationTemplate;
        public Movie()
        {
            validationTemplate = new ValidationTemplate(this);
        }

        private int _id;
        private string _title;
        public int Id
        {
            get { return _id; }
            set
            {
                if (_id != value)
                {
                    _id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

        [Required]
        [StringLength(30)]
        [MinLength(3)]
        public string Title
        {
            get { return _title; }
            set
            {
                if (_title != value)
                {
                    _title = value;
                    OnPropertyChanged("Title");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }

XAML

<TextBox Text="{Binding Movie.Title, Mode=TwoWay, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, NotifyOnValidationError=True, ValidatesOnNotifyDataErrors=True, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
1

There are 1 answers

0
Rahul On BEST ANSWER

I have investigated and found the issue. The below configuration was missing in FodyWeavers.xml file.

<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
  <Validar/>
</Weavers>

The node <Validar/> was removed when i updated the Fody nuget package.