/// <summary> /// When a complex property on this instance changes, this method performs /// the necessary attach/detach operations for the new instance. /// </summary> /// <param name="metaMember">The complex member.</param> private void AttachComplexObjectInstance(MetaMember metaMember) { // First check if the parent has an existing instance attached for this // property and detach if necessary. string memberName = metaMember.Member.Name; ComplexObject prevInstance = null; if (this.TrackedInstances.TryGetValue(memberName, out prevInstance)) { prevInstance.Detach(); this.TrackedInstances.Remove(memberName); } ComplexObject newInstance = (ComplexObject)metaMember.GetValue(this); if (newInstance != null) { // Attach to the new instance newInstance.Attach(this, memberName, this.OnDataMemberChanging, this.OnDataMemberChanged, this.OnMemberValidationChanged); this.TrackedInstances[memberName] = newInstance; // If the instance has validation errors, we need to sync them into our parent. This // needs to be done as a merge operation, since the parent may already have property // level errors for this member that must be retained. if (newInstance.HasValidationErrors) { foreach (ValidationResult error in ValidationUtilities.ApplyMemberPath(newInstance.ValidationErrors, memberName)) { this.ValidationResultCollection.Add(error); } } } }
/// <summary> /// When a result is manually added to the collection, we must add it /// to our parents collection. /// </summary> /// <param name="item">The result to add</param> protected override void OnAdd(ValidationResult item) { if (this._complexObject._parent != null) { // transform the error by adding our parent property to the member names item = ValidationUtilities.ApplyMemberPath(item, this._complexObject._parentPropertyName); // add the result to our parents error collection ICollection <ValidationResult> resultCollection = GetValidationResults(this._complexObject._parent); resultCollection.Add(item); } }
private void NotifyParentMemberValidationChanged(string propertyName, IEnumerable <ValidationResult> validationResults) { if (this.IsAttached) { // notify our parent of the errors, appending the property path to the results IEnumerable <ValidationResult> parentValidationResults = ValidationUtilities.ApplyMemberPath(validationResults, this._parentPropertyName); string propertyPath = this._parentPropertyName; if (!string.IsNullOrEmpty(propertyName)) { propertyPath = propertyPath + "." + propertyName; } this._onMemberValidationChanged(propertyPath, parentValidationResults); } }
/// <summary> /// When a result is manually removed from the collection, we must remove /// it from our parents collection. /// </summary> /// <param name="item">The result to remove</param> protected override void OnRemove(ValidationResult item) { if (this._complexObject._parent != null) { // transform the error by adding our parent property to the member names item = ValidationUtilities.ApplyMemberPath(item, this._complexObject._parentPropertyName); // search (by value) for the item in our parents error collection ICollection <ValidationResult> resultCollection = GetValidationResults(this._complexObject._parent); ValidationResultEqualityComparer comparer = new ValidationResultEqualityComparer(); item = resultCollection.FirstOrDefault(p => comparer.Equals(p, item)); if (item != null) { resultCollection.Remove(item); } } }