Silverlight basics. Validation. Part 1. DataAnnotations & ValidatesOnExceptions
- modified:
- reading: 8 minutes
Silverlight 4 has some new ways for validate input values (some new approaches to implement validation in your application). First approach is DataAnnotation. In this case you should describe validation rules with attributes. Two other ways (both of them is came with Silverlight 4) – you should implement one of interfaces for your ViewModel: IDataErrorInfo or INotifyDataErrorInfo. I want to talk about all of these approaches, about pros and cons of using each of them. Goal of this article to get a best way to implement validation of input values in my and your applications. This part of article about DataAnnotations.
Background
I have example. I want to describe all of these approaches on simple control “change password”.
It has two controls PasswordBox, one button and ValidationSummary. Each sample will have own ViewModel, but XAML of UserControl will be the same:
```xmlI had set 4 properties referred to validation in bindings for password boxes. For now I will tell only about NotifyOnValidationError property. I use it for notify ValidationSummary that some validation errors exist.
PasswordBox has only OneWay binding from control to source (security reason). Binding works only when focus changed (the same like with TextBox). In WPF you can change this behavior, you can set that binding should happened when user press some key (key down event). In Silverlight you can do the same with Attached Property:
```csharp public static class UpdateSourceTriggerHelper { public static readonly DependencyProperty UpdateSourceTriggerProperty = DependencyProperty.RegisterAttached("UpdateSourceTrigger", typeof(bool), typeof(UpdateSourceTriggerHelper), new PropertyMetadata(false, OnUpdateSourceTriggerChanged)); public static bool GetUpdateSourceTrigger(DependencyObject d) { return (bool)d.GetValue(UpdateSourceTriggerProperty); } public static void SetUpdateSourceTrigger(DependencyObject d, bool value) { d.SetValue(UpdateSourceTriggerProperty, value); } private static void OnUpdateSourceTriggerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.NewValue is bool && d is PasswordBox) { PasswordBox textBox = d as PasswordBox; textBox.PasswordChanged -= PassportBoxPasswordChanged; if ((bool)e.NewValue) textBox.PasswordChanged += PassportBoxPasswordChanged; } } private static void PassportBoxPasswordChanged(object sender, RoutedEventArgs e) { var frameworkElement = sender as PasswordBox; if (frameworkElement != null) { BindingExpression bindingExpression = frameworkElement.GetBindingExpression(PasswordBox.PasswordProperty); if (bindingExpression != null) bindingExpression.UpdateSource(); } } } ```If you want use it you should set this attached property for password box:
```xmlI will not use any frameworks, so I need own DelegateCommand (class which implements ICommand interface):
```csharp public class DelegateCommand : ICommand { private readonly Action