nabulke nabulke - 2 months ago 12
C# Question

How to extend validation of a subitem of my viewmodel?

My model class

Animal
implements
INotifyDataErrorInfo
to add validation. My view is bound to a viewmodel with a property
SelectedAnimal
of type
Animal
like that:

View

<TextBox Text="{Binding SelectedAnimal.Epc, UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True}" />


ViewModel

public Animal SelectedAnimal
{
get
{
return _animal;
}
set
{
Set(() => Animal, ref _animal, value);
}
}


Error visualization works fine:

enter image description here

Question



I want to add additional validation, of the field EPC that is done in my viewmodel not in the
Animal
class. So I want to add another validation rule (e.g. check if EPC is unique), that is visualized with the EPC TextBox.

How can I achieve this? Validation errors of that viewmodel rule should also be shown on the EPC TextBox.

I tried manipulating the list of validation errors of class Animal without success.




Additional info

validation based on class ValidatableModel

Answer

This is one way to solve your problem:

  • Wrap the property whose validation you want to extend in your viewmodel

    public string Epc
    {
        get
        {
           return _epc;
        }
        set
        {
           Animal.Epc = value;
           Set(() => Epc, ref _epc, value, false);
        }
    }
    
  • Add two custom validation rules to that property

    [CustomValidation(typeof(ViewModel), "AnimalEpcValidate")]
    [CustomValidation(typeof(ViewModel), "ExtendedEpcValidate")]
    
  • Add your extended validation code, that is not done by Animal itself, to ExtendedEpcValidate

  • Call the Animal.Epc validation and add the results to the Epc validation results in your viewmodel

    public static ValidationResult AnimalEpcValidate(object obj, ValidationContext context)
    {
        var aevm = context.ObjectInstance as ViewModel;
    
        // get errors from Animal validation
        var animalErrors = aevm.Animal.GetErrors("Epc")?.Cast<string>();
    
        // add errors from Animal validation to your Epc validation results
        var error = animalErrors?.Aggregate(string.Empty, (current, animalError) => current + animalError);
    
        // return aggregated errors of Epc property
        return string.IsNullOrEmpty(error)
                   ? ValidationResult.Success
                   : new ValidationResult(error, new List<string> { "Epc" });
    }
    
Comments