/// <summary>
        /// Updates the DataGrid's validation results, modifies the ValidationSummary's items,
        /// and sets the IsValid states of the UIElements.
        /// </summary>
        /// <param name="newValidationResults">New validation results.</param>
        /// <param name="scrollIntoView">If the validation results have changed, scrolls the editing row into view.</param>
        private void UpdateValidationResults(List<ValidationResult> newValidationResults, bool scrollIntoView)
        {
            bool validationResultsChanged = false;
            Debug.Assert(this.EditingRow != null);

            // Remove the validation results that have been fixed
            List<ValidationResult> removedValidationResults = new List<ValidationResult>();
            foreach (ValidationResult oldValidationResult in this._validationResults)
            {
                if (oldValidationResult != null && !newValidationResults.ContainsEqualValidationResult(oldValidationResult))
                {
                    removedValidationResults.Add(oldValidationResult);
                    validationResultsChanged = true;
                }
            }
            foreach (ValidationResult removedValidationResult in removedValidationResults)
            {
                this._validationResults.Remove(removedValidationResult);
                if (this._validationSummary != null)
                {
                    ValidationSummaryItem removedValidationSummaryItem = this.FindValidationSummaryItem(removedValidationResult);
                    if (removedValidationSummaryItem != null)
                    {
                        this._validationSummary.Errors.Remove(removedValidationSummaryItem);
                    }
                }
            }

            // Add any validation results that were just introduced
            foreach (ValidationResult newValidationResult in newValidationResults)
            {
                if (newValidationResult != null && !this._validationResults.ContainsEqualValidationResult(newValidationResult))
                {
                    this._validationResults.Add(newValidationResult);
                    if (this._validationSummary != null && ShouldDisplayValidationResult(newValidationResult))
                    {
                        ValidationSummaryItem newValidationSummaryItem = this.CreateValidationSummaryItem(newValidationResult);
                        if (newValidationSummaryItem != null)
                        {
                            this._validationSummary.Errors.Add(newValidationSummaryItem);
                        }
                    }
                    validationResultsChanged = true;
                }
            }

            if (validationResultsChanged)
            {
                this.UpdateValidationStatus();
            }
            if (!this.IsValid && scrollIntoView)
            {
                // Scroll the row with the error into view.
                int editingRowSlot = this.EditingRow.Slot;
                if (this._validationSummary != null)
                {
                    // If the number of errors has changed, then the ValidationSummary will be a different size,
                    // and we need to delay our call to ScrollSlotIntoView
                    this.InvalidateMeasure();
                    this.Dispatcher.BeginInvoke(delegate
                    {
                        // It's possible that the DataContext or ItemsSource has changed by the time we reach this code,
                        // so we need to ensure that the editing row still exists before scrolling it into view
                        if (!this.IsSlotOutOfBounds(editingRowSlot))
                        {
                            this.ScrollSlotIntoView(editingRowSlot, false /*scrolledHorizontally*/);
                        }
                    });
                }
                else
                {
                    this.ScrollSlotIntoView(editingRowSlot, false /*scrolledHorizontally*/);
                }
            }
        }
        private bool ValidateEditingRow()
        {
            if (this.EditingRow != null)
            {
                List<ValidationResult> newValidationResults = new List<ValidationResult>();
                ValidationContext context = new ValidationContext(this.EditingRow.DataContext, null, null);

                if (!Validator.TryValidateObject(this.EditingRow.DataContext, context, newValidationResults, true))
                {
                    bool validationResultsChanged = false;

                    // Remove the validation results that have been fixed
                    List<ValidationResult> removedValidationResults = new List<ValidationResult>();
                    foreach (ValidationResult oldValidationResult in this._validationResults)
                    {
                        if (oldValidationResult != null && !newValidationResults.ContainsEqualValidationResult(oldValidationResult))
                        {
                            removedValidationResults.Add(oldValidationResult);
                            validationResultsChanged = true;
                        }
                    }
                    foreach (ValidationResult removedValidationResult in removedValidationResults)
                    {
                        this._validationResults.Remove(removedValidationResult);
                        if (this._validationSummary != null)
                        {
                            ValidationSummaryItem removedValidationSummaryItem = this.FindValidationSummaryItem(removedValidationResult);
                            if (removedValidationSummaryItem != null)
                            {
                                this._validationSummary.Errors.Remove(removedValidationSummaryItem);
                            }
                        }
                    }

                    // Add any validation results that were just introduced
                    foreach (ValidationResult newValidationResult in newValidationResults)
                    {
                        if (newValidationResult != null && !this._validationResults.ContainsEqualValidationResult(newValidationResult))
                        {
                            this._validationResults.Add(newValidationResult);
                            if (this._validationSummary != null)
                            {
                                ValidationSummaryItem newValidationSummaryItem = this.CreateValidationSummaryItem(newValidationResult);
                                if (newValidationSummaryItem != null)
                                {
                                    this._validationSummary.Errors.Add(newValidationSummaryItem);
                                }
                            }
                            validationResultsChanged = true;
                        }
                    }

                    // Scroll the row with the error into view
                    int editingRowSlot = this.EditingRow.Slot;
                    if (validationResultsChanged && this._validationSummary != null)
                    {
                        // If the number of errors has changed, then the ValidationSummary will be a different size,
                        // and we need to delay our call to ScrollSlotIntoView
                        this.InvalidateMeasure();
                        this.Dispatcher.BeginInvoke(delegate
                        {
                            // It's possible that the DataContext or ItemsSource has changed by the time we reach this code,
                            // so we need to ensure that the editing row still exists before scrolling it into view
                            if (!this.IsSlotOutOfBounds(editingRowSlot))
                            {
                                this.ScrollSlotIntoView(editingRowSlot, false /*scrolledHorizontally*/);
                            }
                        });
                    }
                    else
                    {
                        this.ScrollSlotIntoView(editingRowSlot, false /*scrolledHorizontally*/);
                    }

                    this.IsValid = this.EditingRow.IsValid = false;
                    this.EditingRow.ApplyState(true);
                    return false;
                }
            }

            // No validation errors, so reset the status
            ResetValidationStatus();
            return true;
        }