DataErrorInfo.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ComponentModel;
  6. using System.ComponentModel.DataAnnotations;
  7. using System.Reflection;
  8. namespace OpenSEMI.ClientBase
  9. {
  10. public class DataErrorInfo<T>
  11. : IDataErrorInfo where T : class
  12. {
  13. private readonly T ImplementorInstance;
  14. private Dictionary<string, Func<T, object>> PropertyGetterMap;
  15. private Dictionary<string, ValidationAttribute[]> ValidatorMap;
  16. private bool HasInitialisedValidator;
  17. public DataErrorInfo(T implementator)
  18. {
  19. ImplementorInstance = implementator;
  20. }
  21. #region Implementation of IDataErrorInfo
  22. public string this[string propertyName]
  23. {
  24. get
  25. {
  26. if (!HasInitialisedValidator) InitialiseValidators();
  27. if (PropertyGetterMap.ContainsKey(propertyName))
  28. {
  29. var propertyValue = PropertyGetterMap[propertyName](ImplementorInstance);
  30. var errorMessages = ValidatorMap[propertyName]
  31. .Where(v => !v.IsValid(propertyValue))
  32. .Select(v => v.ErrorMessage).ToArray();
  33. return string.Join(Environment.NewLine, errorMessages);
  34. }
  35. return string.Empty;
  36. }
  37. }
  38. public string Error
  39. {
  40. get
  41. {
  42. if (!HasInitialisedValidator) InitialiseValidators();
  43. var errors = from validator in ValidatorMap
  44. from attribute in validator.Value
  45. where !attribute.IsValid(PropertyGetterMap[validator.Key](ImplementorInstance))
  46. select attribute.ErrorMessage;
  47. return string.Join(Environment.NewLine, errors.ToArray());
  48. }
  49. }
  50. private void InitialiseValidators()
  51. {
  52. HasInitialisedValidator = true;
  53. ValidatorMap = ImplementorInstance.GetType()
  54. .GetProperties()
  55. .Where(p => GetValidations(p).Length != 0)
  56. .ToDictionary(p => p.Name, GetValidations);
  57. PropertyGetterMap = ImplementorInstance.GetType()
  58. .GetProperties()
  59. .Where(p => GetValidations(p).Length != 0)
  60. .ToDictionary(p => p.Name, GetValueGetter);
  61. }
  62. private static ValidationAttribute[] GetValidations(PropertyInfo property)
  63. {
  64. return (ValidationAttribute[])property.GetCustomAttributes(typeof(ValidationAttribute), true);
  65. }
  66. private static Func<T, object> GetValueGetter(PropertyInfo property)
  67. {
  68. return viewmodel => property.GetValue(viewmodel, null);
  69. }
  70. #endregion Implementation of IDataErrorInfo
  71. }
  72. }