/// <summary> /// Enumerates the current validation results for the specified object. /// </summary> /// <param name="obj">The object for which validation results are needed.</param> /// <returns>The validation results.</returns> public IEnumerable <ValidationResult> EnumerateValidationResults(ISupportValidation obj) { HashCollection <ValidationResult> validationResults; if (this.validationResults.TryGetValue(obj, out validationResults)) { foreach (ValidationResult validationResult in validationResults) { yield return(validationResult); } } }
private void OnPropertyChanged(ModelObject sender, UndoablePropertyChangedEventArgs args) { ISupportValidation obj = sender as ISupportValidation; if (obj != null) { PropertyDescriptor propertyDescriptor = Utilities.GetPropertyDescriptor(sender, args.PropertyName); if (propertyDescriptor.Attributes.Contains(AffectsValidityAttribute.Yes)) { this.BeginValidation(obj); } } }
internal static void Validate(this ISupportValidation validating, string subject) { try { validating.Validate(); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw new BindingException(string.Format("{0} is not valid: {1}.", subject, exception.Message), exception); } }
/// <summary> /// Starts a complete validation of the specified data object. /// </summary> /// <param name="obj">The object to validate.</param> protected void BeginValidation(ISupportValidation obj) { if (obj != null) { lock (this.validationQueue) { if (!this.validationQueue.Contains(obj)) { this.validationQueue.Add(obj); this.Status = ValidationStatus.Validating; this.queueResetEvent.Set(); } } } }
internal static void Validate(this ISupportValidation validating, string subject) { try { validating.Validate(); } catch (Exception exception) when(!exception.IsFatal()) { var message = $"{subject} is not valid: {exception.Message}"; if (!message.EndsWith(".")) { message += "."; } throw new BindingException(message, exception); } }
private void RegisterModelObject(ModelObject modelObject) { lock (this.registeredObjects) { // Make sure the ModelObject hasn't already been processed if (modelObject != null && !this.registeredObjects.Contains(modelObject)) { // Add the object to the list of already processed objects this.registeredObjects.Add(modelObject); // Add the object to the validation manager ISupportValidation obj = modelObject as ISupportValidation; if (obj != null) { this.AddObject(obj); this.BeginValidation(obj); } // Examine the properties of the ModelObject to look for more ModelObjects to process foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(modelObject)) { // Check if the property itself is a ModelObject if (propertyDescriptor.PropertyType.IsSubclassOf(typeof(ModelObject))) { // Recurse on the ModelObject property this.RegisterModelObject((ModelObject)propertyDescriptor.GetValue(modelObject)); } // Check if the property is a collection of child ModelObjects else if (typeof(IEnumerable).IsAssignableFrom(propertyDescriptor.PropertyType)) { INotifyingCollection notifyingCollection = propertyDescriptor.GetValue(modelObject) as INotifyingCollection; if (notifyingCollection != null) { // Recurse on ModelObject children foreach (object childObject in notifyingCollection) { this.RegisterModelObject(childObject as ModelObject); } } } } } } }
/// <summary> /// Adds an object to the Validation Manager. /// </summary> /// <param name="obj">The object to add.</param> protected void AddObject(ISupportValidation obj) { lock (this.objects) { lock (this.validationResults) { if (!this.objects.Contains(obj)) { this.objects.Add(obj); ISupportValidationNotification notifyValidityAffected = obj as ISupportValidationNotification; if (notifyValidityAffected != null) { notifyValidityAffected.ValidityAffected += this.OnValidityAffected; } this.validationResults.Add(obj, new HashCollection <ValidationResult> ()); } } } }
protected bool ValidateProperty(object value, string propertyName) { var validationResults = ValidationHelper.ValidateProperty(this, value, propertyName); ISupportValidation validation = this; validation.OnPropertyValidating(value, propertyName, validationResults); if (validationResults.Count > 0) { AddErrors(propertyName, validationResults); } else { ClearErrors(propertyName); } RaiseErrorsChanged(propertyName); validation.OnPropertyValidated(propertyName); return(!Errors.ContainsKey(propertyName) || Errors[propertyName].Count == 0); }
/// <summary> /// Removes an object from the Validation Manager. /// </summary> /// <param name="obj">The object to be removed.</param> protected void RemoveObject(ISupportValidation obj) { lock (this.objects) { lock (this.validationResults) { lock (this.validationQueue) { if (this.objects.Contains(obj)) { this.objects.Remove(obj); ISupportValidationNotification notifyValidityAffected = obj as ISupportValidationNotification; if (notifyValidityAffected != null) { notifyValidityAffected.ValidityAffected -= this.OnValidityAffected; } HashCollection <ValidationResult> validationResults = this.validationResults[obj]; foreach (ValidationResult validationResult in new List <ValidationResult> (validationResults)) { validationResults.Remove(validationResult); ValidationResult currentValidationResult = validationResult; SendOrPostCallback raiseRemovedEvent = delegate { this.RaiseValidationResultRemovedEvent(currentValidationResult); }; this.asyncOperation.Post(raiseRemovedEvent, null); } this.validationResults.Remove(obj); if (this.validationQueue.Contains(obj)) { this.validationQueue.Remove(obj); } } } } } }
private void BeginValidation() { ThreadStart beginValidation = delegate { while (true) { // Wait if there is no work to do this.queueResetEvent.WaitOne(); ISupportValidation obj = null; lock (this.validationQueue) { if (this.validationQueue.Count == 0) { this.Status = ValidationStatus.Ready; this.queueResetEvent.Reset(); continue; } else { obj = this.validationQueue[0]; this.validationQueue.RemoveAt(0); } } lock (this.validationResults) { // Try to get the validation results (they may have been removed by a different // thread calling RemoveObject) HashCollection <ValidationResult> oldValidationResults; if (this.validationResults.TryGetValue(obj, out oldValidationResults)) { HashCollection <ValidationResult> newValidationResults = new HashCollection <ValidationResult> (); foreach (ValidationResult validationResult in obj.Validate()) { if (!newValidationResults.Contains(validationResult)) { newValidationResults.Add(validationResult); } } foreach (ValidationResult validationResult in new List <ValidationResult> (oldValidationResults)) { if (!newValidationResults.Contains(validationResult)) { oldValidationResults.Remove(validationResult); ValidationResult currentValidationResult = validationResult; SendOrPostCallback raiseRemovedEvent = delegate { this.RaiseValidationResultRemovedEvent(currentValidationResult); }; this.asyncOperation.Post(raiseRemovedEvent, null); } } foreach (ValidationResult validationResult in newValidationResults) { if (!oldValidationResults.Contains(validationResult)) { oldValidationResults.Add(validationResult); ValidationResult currentValidationResult = validationResult; SendOrPostCallback raiseAddedEvent = delegate { this.RaiseValidationResultAddedEvent(currentValidationResult); }; this.asyncOperation.Post(raiseAddedEvent, null); } } } } } }; Thread thread = new Thread(beginValidation); thread.Name = "Validation Manager"; thread.IsBackground = true; thread.Priority = ThreadPriority.BelowNormal; thread.Start(); }
internal static void ClearErrors(System.Collections.Generic.IDictionary <string, HashSet <string> > errors, ISupportValidation isv, string propertyName) { errors.Remove(propertyName); Execute.OnUIThread(() => { isv.RaiseErrorsChanged(propertyName); }); }
internal static void ClearErrors(System.Collections.Generic.IDictionary <string, HashSet <string> > errors, ISupportValidation isv) { var keys = errors.Keys.ToList(); errors.Clear(); Execute.OnUIThread(() => { foreach (var key in keys) { isv.RaiseErrorsChanged(key); } }); }