winform + INotifyPropertyChanged + IDataErrorInfo + ErrorProvider实现自动验证功能

一个简单的Demo.百度下载链接:http://pan.baidu.com/s/1sj4oM2h

话不多说,上代码。

1.实体类定义:

class Student : INotifyPropertyChanged, IDataErrorInfo
    {
        // 用于保存验证错误信息。key 保存所验证的字段名称;value 保存对应的字段的验证错误信息列表
        private Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();

        private const string NAME_ERROR = "name 不能包含空格";
        private const string ID_ERROR = "id 不能小于 10";

        private int age;

        public int Age
        {
            get { return age; }
            set
            {
                if (IsIdValid(value))
                    age = value;
                else
                    age = 0;
                OnPropertyChanged("Age");
            }
        }



        private string stuName;
        public string StuName
        {
            get { return stuName; }
            set
            {
                IsNameValid(value);
                stuName = value;
                OnPropertyChanged("StuName");
            }
        }

        public bool IsIdValid(int value)
        {
            bool isValid = true;

            if (value < 10)
            {
                AddError("Age", ID_ERROR);
                isValid = false;
            }
            else
            {
                RemoveError("Age", ID_ERROR);
            }

            return isValid;
        }

        public bool IsNameValid(string value)
        {
            bool isValid = true;

            if (String.IsNullOrEmpty(value))
            {
                AddError("StuName", NAME_ERROR);
                isValid = false;
            }
            else
            {
                RemoveError("StuName", NAME_ERROR);
            }

            return isValid;
        }


        public void AddError(string propertyName, string error)
        {
            if (!errors.ContainsKey(propertyName))
                errors[propertyName] = new List<string>();

            if (!errors[propertyName].Contains(error))
                errors[propertyName].Add(error);
        }

        public void RemoveError(string propertyName, string error)
        {
            if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error))
            {
                errors[propertyName].Remove(error);

                if (errors[propertyName].Count == 0)
                    errors.Remove(propertyName);
            }
        }

        public string Error
        {
            get { return errors.Count > 0 ? "有验证错误" : ""; }
        }

        public string this[string propertyName]
        {
            get
            {
                if (errors.ContainsKey(propertyName))
                    return string.Join(Environment.NewLine, errors[propertyName]);
                else
                    return null;
            }
        }

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
Student.cs

2.界面Load绑定:

  拖个errorProvider控件,注意绑定方式。

DataSourceUpdateMode.OnPropertyChanged 可以在属性值改变时进行验证提示。
 public partial class Form1 : Form
    {
        Student stu = new Student() { StuName = "", Age = 0 };
        public Form1()
        {
            InitializeComponent();
            this.textBox1.DataBindings.Add(new Binding("Text", stu, "StuName", false, DataSourceUpdateMode.OnValidation));
            this.textBox2.DataBindings.Add(new Binding("Text", stu, "Age", false, DataSourceUpdateMode.OnValidation));
            this.errorProvider1.DataSource = stu;
        }

    }

3.判断是否包含错误

直接判断Student对象的Error属性是否为空即可

4.多个实体需要判断,可以抽出个类,根据自己需要扩展对应方法

public class DataErrorInfoCommon
    {
        // 用于保存验证错误信息。key 保存所验证的字段名称;value 保存对应的字段的验证错误信息列表
        public Dictionary<String, List<String>> errors = new Dictionary<string, List<string>>();

        public string Error
        {
            get { return errors.Count > 0 ? "有验证错误" : ""; }
        }

        public string This(string propertyName)
        {
            if (errors.ContainsKey(propertyName))
                return string.Join(Environment.NewLine, errors[propertyName]);
            else
                return null;
        }

        #region IDataErrorInfo验证方法
        private const string REQUIRED = "不能为空";
        private const string NUMBER = "请输入数字";
        private const string LENGTH_CROSS = "长度超过限制{0}";

        /// <summary>
        /// 添加错误消息
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="error">错误消息</param>
        public void AddError(string propertyName, string error)
        {
            if (!errors.ContainsKey(propertyName))
                errors[propertyName] = new List<string>();

            if (!errors[propertyName].Contains(error))
                errors[propertyName].Add(error);
        }

        /// <summary>
        /// 移除错误消息
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="error">错误消息</param>
        public void RemoveError(string propertyName, string error)
        {
            if (errors.ContainsKey(propertyName) && errors[propertyName].Contains(error))
            {
                errors[propertyName].Remove(error);

                if (errors[propertyName].Count == 0)
                    errors.Remove(propertyName);
            }
        }

        /// <summary>
        /// 判断是否为空
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="value">属性值</param>
        /// <returns></returns>
        public bool IsEmpty(string propertyName, string value)
        {
            bool isEmpty = false;
            if (String.IsNullOrWhiteSpace(value))
            {
                AddError(propertyName, REQUIRED);
                isEmpty = true;
            }
            else
                RemoveError(propertyName, REQUIRED);
            return isEmpty;
        }

        /// <summary>
        /// 判断内容是否是数字
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="value">属性值</param>
        /// <returns></returns>
        public bool IsNumber(string propertyName, string value)
        {
            bool isNumber = true;
            int num = -1;
            if (!int.TryParse(value, out num))
            {
                AddError(propertyName, NUMBER);
                isNumber = false;
            }
            else
                RemoveError(propertyName, NUMBER);
            return isNumber;
        }

        /// <summary>
        /// 判断长度是否超过限制
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="value">属性值</param>
        /// <param name="length">长度限制</param>
        /// <returns></returns>
        public bool IsCrossLenght(string propertyName, string value, int length)
        {
            bool isCross = false;
            if (value.Length > length)
            {
                AddError(propertyName, string.Format(LENGTH_CROSS, length));
                isCross = true;
            }
            else
                RemoveError(propertyName, string.Format(LENGTH_CROSS, length));
            return isCross;
        }
        #endregion
    }
View Code

5.使用验证类

 //定义验证类对象
 public DataErrorInfoCommon dataErrorCommon = null;

//在构造函数中初始化
dataErrorCommon =new DataErrorInfoCommon();

//使用
        private string stuName;
        public string StuName
        {
            get { 
                    dataErrorCommon.IsEmpty("StuName", stuName);
                    return stuName; 
            }
            set
            {
                dataErrorCommon.IsEmpty("StuName",value);
                stuName = value;
                OnPropertyChanged("StuName");
            }
        }        



        public event PropertyChangedEventHandler PropertyChanged;
        /// 属性改变通知事件
        /// </summary>
        /// <param name="propertyName">属性通知</param>
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public string Error
        {
            get { return dataErrorCommon.Error; }
        }

        public string this[string propertyName]
        {
            get
            {
                return dataErrorCommon.This(propertyName);
            }
        }
View Code
原文地址:https://www.cnblogs.com/xcong/p/3617688.html