Data Validation in Silverlight 4

I have control in SL4. I want the data check is clicked on. The big problem, as a rule, SL4 gives confirmation using the binding property.

Example shown in this example

http://weblogs.asp.net/dwahlin/archive/2010/08/15/validating-data-in-silverlight-4-applications-idataerrorinfo.aspx

<TextBox Text="{Binding Name,Mode=TwoWay,ValidatesOnDataErrors=true}" Height="23" Width="120" HorizontalAlignment="Left" VerticalAlignment="Top" /> 

BUT I WANT TO SHOW AN ERROR MESSAGE AS IT IS ....

enter image description here

using my own code, for example, on the click button, I check (textbox1.text == null), then set this error style to textbox1

+6
validation silverlight
source share
2 answers

One way to defer validation is to set the UpdateSourceTrigger=Explicit property in the bindings. If you do this, the bindings will not update the original objects and, therefore, will not cause validation errors until you explicitly specify the bindings for this. When you click the button, you force the bindings to be updated using the following line for each element:

 someTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 

Then you have your property developers throwing exceptions for invalid data.

This approach can be a little painful if there are enough controls to force the binding to be updated.

In addition, forced binding updates must be performed in the control code of the control. If you also use a command with a button, you may run into a problem. Buttons can have either a Command or Click handler, and both will be executed when the button is clicked, but I donโ€™t know in what order this happens or even if the order can be guaranteed. A quick experiment showed that the event handler was executed before the command, but I do not know if this behavior is undefined. Therefore, it is likely that the command will be run before the bindings are updated.


The programming approach for creating validation tooltips is to associate another property of the text field, and then deliberately cause an error with this binding.

'sapient' posted the complete solution, including code on the Silverlight forums (search for message from 08/07/2009 4:56 PM). In short, it creates an auxiliary object with a property whose receiver throws an exception, binds the Tag property of the text field to this auxiliary object, and then forces the binding to be updated.

'sapient code was written before the release of Silverlight 4. We will upgrade his / her code to Silverlight 4. The ControlValidationHelper class will become:

 public class ControlValidationHelper : IDataErrorInfo { public string Message { get; set; } public object ValidationError { get; set; } public string Error { get { throw new NotImplementedException(); } } public string this[string columnName] { get { return Message; } } } 

It's easy enough to knock out a quick demo app to try this. I created the following three controls:

  <TextBox x:Name="tbx" Text="{Binding Path=Text, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=TwoWay}" /> <Button Click="ForceError_Click">Force error</Button> <Button Click="ClearError_Click">Clear error</Button> 

The Text property and event handlers for two buttons live in the code and look like this:

  public string Text { get; set; } private void ForceError_Click(object sender, RoutedEventArgs e) { var helper = new ControlValidationHelper() { Message = "oh no!" }; tbx.SetBinding(Control.TagProperty, new Binding("ValidationError") { Mode = BindingMode.TwoWay, NotifyOnValidationError = true, ValidatesOnDataErrors = true, UpdateSourceTrigger = UpdateSourceTrigger.Explicit, Source = helper }); tbx.GetBindingExpression(Control.TagProperty).UpdateSource(); } private void ClearError_Click(object sender, RoutedEventArgs e) { BindingExpression b = tbx.GetBindingExpression(Control.TagProperty); if (b != null) { ((ControlValidationHelper)b.DataItem).Message = null; b.UpdateSource(); } } 

The Power Error button should make a validation error in the text box, and the Clear Error button should go away.

One potential drawback of this approach arises if you use ValidationSummary . ValidationSummary will list all validation errors with a ValidationError instead of the name of each property.

+9
source share

Although my answer was not considered preferable, I'm still sure that the MVVM pattern is the best choice to check.

In my code you should use the model validator this post about validation and any mvvm infrastructure like MVVM Light.

It is much easier to add validation rules using models of the presentation model and the validator model:

 public class PersonViewModel : ViewModelBase, INotifyDataErrorInfo { private ModelValidator _validator = new ModelValidator(); public PersonViewModel() { this._validator.AddValidationFor(() => this.Age) .Must(() => this.Age > 0) .Show("Age must be greater than zero"); } } 

And you can check the model if and only if the user explicitly clicks the button:

  #region INotifyDataErrorInfo public IEnumerable GetErrors(string propertyName) { return this._validator.GetErrors(propertyName); } public bool HasErrors { get { return this._validator.ErrorMessages.Count > 0; } } public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { }; protected void OnErrorsChanged(string propertyName) { ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); this.RaisePropertyChanged("HasErrors"); } #endregion public bool Validate() { var result = this._validator.ValidateAll(); this._validator.PropertyNames.ForEach(OnErrorsChanged); return result; } 

As you can see everything, there is nothing complicated, just 20-30 lines of code.

In addition, the MVVM approach is much more flexible, and you can reuse some common validation scripts among several view models.

+3
source share

All Articles