简体   繁体   中英

How to validate child objects by implementing IDataErrorInfo on parent class and how to bind validation to objects

I want to ask exactly the same question that was asked in this link and also a person answered too but I couldn't understand how to incorporate that in the code. Sorry for asking the noob question, please bear with me.

the link for the question is How to validate child objects by implementing IDataErrorInfo on parent class .

Question is exactly the same and answer is how to achieve but what I find lacking is how to use that class for validation in Employee class.

I'm posting the same question below: I have two model classes. Parent class has an object of another (child) class as its property. (i mean nested objects and not inherited objects)

public class AddEditItemVM
{
    #region Properties/Fields

    //validate here: Category cannot be empty, it has to be selected
    public Category SelectedCategory
    {
        get => _SelectedCategory;
        set 
        { 
            _SelectedCategory = value;
            OnPropertyChanged(nameof(SelectedCategory));
        }
    }
    private Category _SelectedCategory = new CCategory();

    public Items Source
    {
        get => _Source;
        set 
        { 
            _Source = value; 
            OnPropertyChanged(nameof(Source));
        }
    }
    private Items _Source = new Items();

    #endregion Properties/Fields
}

Category class is

public class Category 
{
    #region Properties/Fields

    public long Id
    {
        get => _Id;
        set
        {
            _Id = value;
            OnPropertyChanged(nameof(Id));
        }
    }
    long _Id;

    public string Name
    {
        get => _Name;
        set
        {
            _Name = value;
            OnPropertyChanged(nameof(Name));
        }
    }
    private string _Name;

    #endregion Properties/Fields
}

Items class is

public class Items
{
    #region Properties/Fields

    public int CategoryID
    {
        get => _CategoryID;
        set
        {
            _CategoryID = value;
            OnPropertyChanged(nameof(CategoryID));
        }
    }
    int _CategoryID;
    
    //I want to validate this, item name cannot be empty and cannot greater than 20 characters
    public string Name
    {
        get => _Name;
        set
        {
            _Name = value;
            OnPropertyChanged(nameof(Name));
        }
    }
    string _Name = String.Empty;

    //validate for percentage like percentage should be between 1 and 100
    public decimal? TaxPerc
    {
        get => _TaxPerc;
        set
        {
            //_TaxPerc = value;
            _TaxPerc = Properties.Settings.Default.GSTPerc;
            OnPropertyChanged(nameof(TaxPerc));
            OnPropertyChanged(nameof(PricePlsTax));
            OnPropertyChanged(nameof(TaxAmount));
        }
    }
    decimal? _TaxPerc = null;

    //price cannot be 0
    //* required field!
    public decimal? Price
    {
        get => _Price;
        set
        {
            _Price = value;
            OnPropertyChanged(nameof(Price));
            OnPropertyChanged(nameof(PricePlsTax));
            OnPropertyChanged(nameof(TaxAmount));
        }
    }
    decimal? _Price = null;
    #endregion Properties/Fields
}

and the person answered with validation with IDataErrorInfo (which is what I want)

public abstract class DataErrorInfo : IDataErrorInfo
{
    string IDataErrorInfo.Error
    {
        get { return string.Empty; }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            var prop = this.GetType().GetProperty(columnName);
            return this.GetErrorInfo(prop); 
        }
    }

    private string GetErrorInfo(PropertyInfo prop)
    {
        var validator = this.GetPropertyValidator(prop);

        if (validator != null)
        {
           var results = validator.Validate(this);

           if (!results.IsValid)
           {
              return string.Join(" ",
                  results.Select(r => r.Message).ToArray());
           }
        }

        return string.Empty;
    }

    private Validator GetPropertyValidator(PropertyInfo prop)
    {
        string ruleset = string.Empty;
        var source = ValidationSpecificationSource.All;
        var builder = new ReflectionMemberValueAccessBuilder();
        return PropertyValidationFactory.GetPropertyValidator(
            this.GetType(), prop, ruleset, source, builder);
    }
}

but I couldn't understand the final part ie implementation I mean how to use this class in the implemented class. He said to implement it by making it the parent class which is as below

public AddEditItemVM : DataErrorInfo
{
}

but I wanna know how to bind the validation with the objects.

<TextBox Text="{Binding SelectedCategory.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"></TextBox>

This will bind to your name property of your selectedcategory class and show if there is any validation errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM