WPF binding. How to identify an object is invalid to prevent saving

I have a text field in a WPF application bound to a property of the Linq to Entities class that implements IDataErrorInfo. Text field binding has ValidatesOnExceptions = True and ValidatesOnDataErrors = True. When the text field is bound to the integer property and the user enters text, the outline of the text field is displayed in red, since I did not configure my own style.

In my Save method, how can I find out that an object cannot be saved because it is not valid? I would prefer the user to click the "Save" button, and I can notify them of the problem, and not disable the "Save" button.

Greetings

Dave

+6
wpf binding
source share
2 answers

I did not find an easy way to do this. I found some code around the traps to recursively go through all the controls on the form and determine if they have validation errors. I turned it into an extension method:

// Validate all dependency objects in a window internal static IList<ValidationError> GetErrors(this DependencyObject node) { // Check if dependency object was passed if (node != null) { // Check if dependency object is valid. // NOTE: Validation.GetHasError works for controls that have validation rules attached bool isValid = !Validation.GetHasError(node); if (!isValid) { // If the dependency object is invalid, and it can receive the focus, // set the focus if (node is IInputElement) Keyboard.Focus((IInputElement)node); return Validation.GetErrors(node); } } // If this dependency object is valid, check all child dependency objects foreach (object subnode in LogicalTreeHelper.GetChildren(node)) { if (subnode is DependencyObject) { // If a child dependency object is invalid, return false immediately, // otherwise keep checking var errors = GetErrors((DependencyObject)subnode); if (errors.Count > 0) return errors; } } // All dependency objects are valid return new ValidationError[0]; } 

So, when the user clicks the "Save" button on the form, I do this:

 var errors = this.GetErrors(); if (errors.Count > 0) { MessageBox.Show(errors[0].ErrorContent.ToString()); return; } 

This is much more than it should be, but using the extension method simplifies it a bit.

+5
source share

You can set NotifyOnValidationError to true on Binding s, and then add a handler for the Error event for any parent element. The event will be fired every time an error is added or removed.

+3
source share

All Articles