Introduction
Data validation is an integral part of any user interface program. In WPF, data validation is tied tightly to bindings, and the following is a brief introduction to several commonly used authentication methods in the MVVM pattern.
Error message Display
Before you introduce data validation, it is necessary to explain how to display error messages. The way is simple, define a style trigger, bind the error message and the ToolTip, as follows:
<style targettype="TextBox"> <Style.Triggers> <trigger property="Validation.haserror"Value="true"> <setter property="ToolTip"Value="{Binding Relativesource={relativesource self}, path= (Validation.errors) [0]. Errorcontent}"/> </Trigger> </Style.Triggers> </Style>
Validatesonexceptions validation Rules
Validatesonexceptions is a predefined validation rule for WPF, which captures exceptions at any location, including type conversion exceptions, property set exceptions, value converter exceptions, and so on. When you catch an exception, the border you enter becomes red, and you can also customize the wrong template ( validation.errortemplate). If you want the validatesonexceptions to take effect, set the validatesonexceptions in the binding property to True.
PS: Whether set to True or FALSE, type conversion exceptions always occur, that is, there will always be a red box.
Validating in Data Objects
Writing validation rules directly in a data object is the simplest and most brutal way, as follows
Public intPrice {Get{return_price;} Set { if(Equals (value, _price))return; if(Value <0) { Throw NewArgumentException ("value cannot be less than 0"); } Else{_price=value; raisePropertyChanged (()=Price ); } } }
If less than 0, the program will not be wrong, the text hint will also appear on the ToolTip, if Validatesonexceptions=true.
PS: This approach can be implemented as expected because the binding of WPF captures all exceptions in the property settings. However, if the code is set to a negative number, the program hangs directly.
Custom validation Rules
In addition to the predefined validation rules for WPF, we can also customize validation rules to inherit ValidationRule, write a value that cannot be greater than 99, and the code is as follows:
Public classNumberrule:validationrule { Public OverrideSystem.Windows.Controls.ValidationResult Validate (Objectvalue, CultureInfo CultureInfo) { inti; //Int. TryParse (value. ToString (), out i); if(!int. TryParse (value. ToString (), outi)) {return NewSystem.Windows.Controls.ValidationResult (false, "The string is not formatted!"); } if(I > About) { return NewSystem.Windows.Controls.ValidationResult (false, "value cannot be greater than 99!"); } Else { return NewSystem.Windows.Controls.ValidationResult (true,NULL); } } }
<textbox height=" -"Width=" -"margin="208,142,0,0"Verticalalignment="Top"Horizontalalignment=" Left"> <TextBox.Text> <binding path=" Price"Mode="TwoWay"validatesondataerrors="True"> <Binding.ValidationRules> <EXCEPTIONVALIDATIONRULE></EXCEP Tionvalidationrule> <local:NumberRule></local:NumberRule> </bi Nding. validationrules> </Binding> </TextBox.Text> </TextBox>
PS: Custom validation rules are always preceded by exceptionvalidationrule, so there is a possibility of throwing the error in the Numberrule with the conversion type, and of course the above code will always return 0 if there is a type fault variable i.
PS: Validation execution order: Custom Validation Rule--value converter->exceptionvalidationrule-> data Object validation.
Validatesondataerrors validation Rules
Under normal circumstances, the above can work very well, but the property up to dozens of times, it is not so comfortable to write. This time we can unify our validation rules by inheriting the interface IDataErrorInfo, the code is as follows:
public string Error {get {return ' ";}} public string this[string PropertyName] { get { string result = null; if (propertyname = = "Price") {if (price >99) {result = "value cannot be greater than 99!!" ; } } return result;}}
The error does not work in WPF and can be returned arbitrarily.
PS: Remember to put Validatesondataerrors=true
PS: Validation execution order: Custom Validation Rule--value converter->exceptionvalidationrule-> data Object validation->validatesondataerrors.
Advanced Validatesondataerrors Validation rules
Although validatesondataerrors can be unified to one place, it is unavoidable to write a single rule for each attribute. So we need a simpler way, that is the way of Dataannotations+idataerrorinfo, the code is as follows:
Private int_price; [Range (0, About, errormessage ="the values are between 0 and 99 .")] Public intPrice {Get{return_price;} Set { if(Equals (value, _price))return; if(Value <0) { Throw NewArgumentException ("value cannot be less than 0"); } Else{_price=value; raisePropertyChanged (()=Price ); } } } Public string This[stringPropertyName] { Get { varVC =NewValidationcontext ( This,NULL,NULL); Vc. MemberName=PropertyName; varres =NewList<system.componentmodel.dataannotations.validationresult>(); varresult = Validator.tryvalidateproperty ( This. GetType (). GetProperty (PropertyName). GetValue ( This,NULL), VC, RES); if(Res. Count >0) { return string. Join (Environment.NewLine, Res. Select (R =r.errormessage). ToArray ()); } return string. Empty; } }
In this way, when developing a simple set of features, you can expect to display our verification hints, the detailed usage of this way, there is a better article on the Internet: Portal.
Precautions
Here, if there is no accident, I believe that everyone will adopt dataannotations+idataerrorinfo way, this way to achieve the simplest, and happen on the ViewModel, we easily in the preservation process to get all the abnormal information, This prevents the data from being saved. However, there is a common problem with data validation in WPF, that is, when data anomalies occur, the actual value of the property is the last valid value, and the value displayed on the interface is different. This time if the user forcibly save, we will find dataannotations+ IDataErrorInfo's verification method has passed! This is not in line with our expectations. I don't see any elegant solution in this situation. The only way to think about it is to traverse the Logicaltreehelper input control in the button's Click event. Check the Validation.haserror property, combine the exception information to ViewModel, let ViewModel make the processing. The most thorough approach is to encapsulate a variety of specific controls, such as digital input controls, to improve the user experience while making exception handling easier.
Summary
This article briefly introduces the various methods of WPF data validation, and we will basically adopt the Dataannotations+idataerrorinfo way, if you have a better way, please feel free, thank you!
"WPF" Data validation