Advertisement
Guest User

Untitled

a guest
Jun 27th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.99 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.ComponentModel.DataAnnotations;
  5. using System.Linq;
  6.  
  7. namespace TM
  8. {
  9. /// <summary>
  10. /// Supports validation according to <see cref="INotifyDataErrorInfo"/> via validation attributes
  11. /// (<see cref="ValidationAttribute"/>) decorating the properties of validated class.
  12. /// Validated class should create an instance of <see cref="ValidatorComponent"/>, passing itself as a parameter.
  13. /// <see cref="HasErrors"/> and <see cref="GetErrors(string)"/> should be delegated
  14. /// to <see cref="ValidatorComponent"/>, while <see cref="ErrorsChanged"/> should be propagated upwards.
  15. /// </summary>
  16. public class ValidatorComponent
  17. {
  18.  
  19. /// <summary>
  20. /// Validation errors grouped by invalid member names
  21. /// </summary>
  22. private Dictionary<string, List<ValidationResult>> _validationErrors
  23. = new Dictionary<string, List<ValidationResult>>();
  24.  
  25.  
  26. /// <summary>
  27. /// Reference to the validated object
  28. /// </summary>
  29. public INotifyPropertyChanged ValidatedInstance { get; private set; }
  30.  
  31. public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
  32.  
  33. /// <summary>
  34. /// Creates new instance of <see cref="ValidatorComponent"/> observing a given <paramref name="validatedInstance"/>.
  35. /// </summary>
  36. /// <param name="validatedInstance">reference to the validated object</param>
  37. public ValidatorComponent(INotifyPropertyChanged validatedInstance)
  38. {
  39. ValidatedInstance = validatedInstance;
  40. ValidatedInstance.PropertyChanged +=
  41. (source, propertyName) => PerformValidation();
  42. PerformValidation();
  43. }
  44.  
  45. public bool HasErrors
  46. {
  47. get { return _validationErrors.Values.Any(item => item != null && item.Count > 0); }
  48. }
  49.  
  50. public System.Collections.IEnumerable GetErrors(string propertyName)
  51. {
  52. if (string.IsNullOrEmpty(propertyName))
  53. return Enumerable.Empty<ValidationResult>();
  54. List<ValidationResult> errors = null;
  55. if (_validationErrors.TryGetValue(propertyName, out errors))
  56. return errors;
  57. return Enumerable.Empty<ValidationResult>();
  58. }
  59.  
  60.  
  61. /// <summary>
  62. /// Validates the <see cref="ValidatedInstance"/>, updates errors collection
  63. /// and notifies listeners via <see cref="ErrorsChanged"/> event.
  64. /// </summary>
  65. public void PerformValidation()
  66. {
  67. var oldMembers = _validationErrors.Values.SelectMany(list => list.SelectMany(x => x.MemberNames)).Distinct().ToList();
  68.  
  69. _validationErrors.Clear();
  70. var context = new ValidationContext(ValidatedInstance);
  71. List<ValidationResult> errors = new List<ValidationResult>();
  72. var result = Validator.TryValidateObject(ValidatedInstance, context, errors, true);
  73.  
  74. foreach (var member in oldMembers)
  75. ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(member));
  76.  
  77. if (result == true)
  78. return;
  79.  
  80. foreach (var error in errors)
  81. {
  82. foreach (var member in error.MemberNames)
  83. {
  84. if (_validationErrors.ContainsKey(member) == false)
  85. _validationErrors[member] = new List<ValidationResult>();
  86. if (_validationErrors[member].Any(err => err.ErrorMessage == error.ErrorMessage))
  87. continue;
  88. _validationErrors[member].Add(error);
  89. }
  90. }
  91.  
  92. ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(string.Empty));
  93.  
  94. var members = errors.SelectMany(x => x.MemberNames).Distinct();
  95. foreach (var member in members)
  96. ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(member));
  97. }
  98.  
  99. }
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement