In this article I will discuss all the ways in which we can validate data in the WPF application. The various WPF validation techniques are as following.
- Validations using Exceptions
- Validation Rules
- Validation using IDataErrorInfo
- Validation using INotifyDataErrorInfo
In this article I will discuss the first two techniques of validation.
Validations using Exceptions
- This is one of the easiest way to do WPF validations.
- If we bind a property to control’s data binding, and if the get or set block of the property throws exception, the exception will be swallowed by the binding itself.
- If the value that is being set is not valid we need to throw the exception to the UI. For this we need to set the ValidatesOnException = true in the binding of the control
- One of the advantage of this validation is that is discards the value of the property before being set to the property variable and don’t store the value in the member variable of class.
Demo For validation With Exception
i will demonstrate the validation with example. I have a simple UI where I have two fields Name and Mobile Number. And a view model which binds to this UI contains two properties. Please check the below code.
public class PersonVM: INotifyPropertyChanged { private string mobileNumber; public string MobileNumber { get { return mobileNumber; } set { ValidatePhone(value); mobileNumber = value; PropertyChanged(this, new PropertyChangedEventArgs("MobileNumber")); } } private string name; public string Name { get { return name; } set { name = value; PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } public event PropertyChangedEventHandler PropertyChanged = delegate { }; private void ValidatePhone(string value) { if (string.IsNullOrEmpty(value)) return; Regex regex = new Regex(@"^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$"); if (regex.Match(value) == Match.Empty) throw new ArgumentException("Invalid phone format"); } }
As seen in the above code I am validating the Mobile Number field for 10 digits. If I am entering less then or more then 10 digits I will get a red border around the control as shown in the below figure
.For getting this validation error on the Text box we have to use the code as shown below.
<TextBlock Text="Mobile Number " Height="30" Grid.Column="0" Grid.Row="1"></TextBlock> <TextBox Text="{Binding MobileNumber, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="1" Height="30" Width="100"></TextBox>
In the C# code snippet you can notice that I am checking for the valid phone number using the ValidatePhone() method. This method is in turn throwing the exception if the phone is not in valid format.
Validation Rules
The other way by which we can validate the input is by using the validation rules. We need to follow following steps to validate using validation rules.
- Derive the class from ValidationRule class.
- Override the Validate abstract method of the base class.
- The Validate method returns the ValidationResult based on the Success/Fail indication. It also returns the error message.
- Once a validation rule is defined. We bind this rule to the ValidationRule collection of the Binding class.
- ValidationRules can be used to encapsulate the reuse-able rules.
- The downside is that they are not context specific.
I will use the same example as above for the demo. The only change is that it is done using ValidationRule.
<TextBox Grid.Column="1" Grid.Row="1" Height="30" Width="100"> <TextBox.Text> <Binding Path="MobileNumber" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:RegexValidationRule Expression="^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$"></local:RegexValidationRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
In the above XAML code you can see that I have used the explicit Text binding. The reason for that is that I can set the validation rules collection with the instance of the RegexValidationRule class. The code for the class is as shown below.
public class RegexValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { Regex regex = new Regex(@"^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$"); Match match = regex.Match(value.ToString()); if (match == null || match == Match.Empty) return new ValidationResult(false, "Invalid input format"); else return ValidationResult.ValidResult; } public string Expression { get; set; } }
In this validation there is no need to call the ValidatePhone() method explicitly as we have done for exception validations.
Conclusion:
In this article I have discussed the two rules to validate the data in WPF application. Next article will contains the other two ways.