DataAnnotations:if(valid)=>改变财产

时间:2012-12-06 10:31:10

标签: validation c#-4.0 mvvm properties data-annotations

嗨,我在谷歌上搜索这个问题,但我没有发现任何关于此的问题。

如果每个DataAnnotations验证失败

,我想要删除属性集

你能告诉我我的代码中缺少什么吗?

Model Codesnip

        private string _firstname;
        public string Firstname
        {
            get { return _firstname; }
            set
            {
                _firstname = value;
                RaisePropertyChanged(() => Reg(() => Firstname));
            }
        }

ViewModel Codesnip

        [Required]
        [RegularExpression(@"^[a-zA-ZäöüßÄÖÜß''-'\s]{2,40}$")]
        public string Name
        {
            get { return currentperson.Name; }
            set
            {
                currentperson.Name = value;
            RaisePropertyChanged(() => Reg(() => Name));
            }
        }

查看Codesnip

<TextBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Text="{Binding Firstname,UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/>

任何帮助将不胜感激

编辑:添加验证类

public class VMValidation : VMBase, IDataErrorInfo
{
    private Dictionary<string, string> ErrorList = new Dictionary<string, string>();

    /// <summary>
    /// Gets a value indicating whether or not this domain object is valid. 
    /// </summary>
    public bool IsVailid
    {
        get { return (ErrorList.Count == 0) ? true : false; }
    }

    #region IDataErrorInfo

    /// <summary>
    /// Gets an error message indicating what is wrong with this domain object. 
    /// The default is an empty string ("").
    /// </summary>
    public string Error
    {
        get { return getErrors(); } // noch keine richtige methode für gefunden müsste so aber auch funktionieren
    }

    /// <summary>
    /// dies ist eine methode die durch einen Event (noch unbekannt welcher)
    /// ausgelöst wird und den Propertynamen schon mit übergeben bekommt
    /// </summary>
    /// <param name="propertyName">Name der Property z.B FirstName</param>
    /// <returns>The error message for the property. 
    /// The default is an empty string ("").</returns>
    public string this[string propertyName]
    {
        get { return OnValidate(propertyName); }
    }

    private string getErrors()
    {
        string Error = "";
        foreach (KeyValuePair<string, string> error in ErrorList)
        {
            Error += error.Value;
            Error += Environment.NewLine;
        }

        return Error;
    }

    /// <summary>
    /// Validates current instance properties using Data Annotations.
    /// </summary>
    /// <param name="propertyName">Name der Property</param>
    /// <returns>ErrorMsg</returns>
    protected virtual string OnValidate(string propertyName)
    {
        if (string.IsNullOrEmpty(propertyName))
            throw new ArgumentException("Invalid property name", propertyName);

        string error = string.Empty;
        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;
        }
        if (error.Length > 0)
        {
            if (!ErrorList.ContainsKey(propertyName))
                ErrorList.Add(propertyName, error);
        }
        else
            if (!ErrorList.ContainsKey(propertyName))
                ErrorList.Remove(propertyName);

        return error;
    }

    public bool VailidValue(string propertyName, object value)
    {
        var results = new List<ValidationResult>(1);
        var context = new ValidationContext(this, null, null) { MemberName = propertyName };
        var result = Validator.TryValidateProperty(value, context, results);

        return result;
    }
    #endregion //IDataErrorInfo
}

2 个答案:

答案 0 :(得分:1)

尝试创建验证方法,并仅在结果为true时设置值。

public string Name
{
    get { return currentperson.Name; }
    set
    {
        if (ValidateProperty("Name", value))
        {
            currentperson.Name = value;
            RaisePropertyChanged(() => Reg(() => Name));
        }
    }
} 

protected bool ValidateProperty(string propertyName, object value)
{
    var results = new List<ValidationResult>();
    bool isValid = Validator.TryValidateProperty(
        value,
        new ValidationContext(this, null)
        {
            MemberName = propertyName
        },
        results);
    // Do what you want with the validation results
    return isValid;
}

答案 1 :(得分:1)

我改变了我的VMValidation

      public class VMValidation : VMBase, IDataErrorInfo
        {
            private Dictionary<string, string> ErrorList = new Dictionary<string, string>();

            public bool IsVailid
            {
                get { return (ErrorList.Count == 0) ? true : false; }
            }

            #region IDataErrorInfo

            public string Error
            {
                get { return getErrors(); } // noch keine richtige methode für gefunden müsste so aber auch funktionieren
            }

            public string this[string propertyName]
            {
                get { return OnValidate(propertyName); }
            }

            private string getErrors()
            {
                string Error = "";
                foreach (KeyValuePair<string, string> error in ErrorList)
                {
                    Error += error.Value;
                    Error += Environment.NewLine;
                }

                return Error;
            }

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

                if (ErrorList.ContainsKey(propertyName))
                    error = ErrorList[propertyName];

                return error;
            }

            public bool VailidateValue(string propertyName, object value)
            {
                if (string.IsNullOrEmpty(propertyName))
                {
                    Logger.ERRROR(propertyName, "Invalid property name");
                    throw new ArgumentException("Invalid property name", propertyName);
                }

                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();
                    string error = validationResult.ErrorMessage;

                    if (error.Length > 0)
                    {
                        if (!ErrorList.ContainsKey(propertyName))
                            ErrorList.Add(propertyName, error);
                    }
                }
                else
                   if (ErrorList.ContainsKey(propertyName))
                       ErrorList.Remove(propertyName);

                return result;
            }
            #endregion //IDataErrorInfo
        }

并做Alyce所建议的

        [Required]
        [RegularExpression(@"^[a-zA-ZäöüßÄÖÜß''-'\s]{2,40}$")]
        public string Name
        {
            get
            {
                if (currentperson == null)
                    return "";
                return currentperson.Name;
            }
            set
            {
                if (VailidateValue("Name", value))
                {
                    currentperson.Name = value;
                }
                RaisePropertyChanged(() => Reg(() => Name)); //you have to Raise because otherwise you won't get the Error :)
            }
        }