The first validation system discussed in this chapter is the property setter validation system. This system has been with the phone since the first 7.0 release of the Windows Phone SDK and is part of Silverlight 3.
The XAML data-binding system provides validation support when assigning a value to the source of a data-binding expression. For example, when a FrameworkElement
(the binding target) has a binding to a property in a viewmodel (the binding source) and the value in the FrameworkElement
changes, validation occurs as the value is being assigned to the property in the viewmodel.
To enable property setter validation for an input control, set the binding’s NotifyOnValidationError
and ValidatesOnExceptions
to true, as shown in the following example:
<TextBox Text="{Binding PropertyName, Mode=TwoWay,
NotifyOnValidationError=True, ValidatesOnExceptions=True}" />
ValidatesOnExceptions
enables property validation for the binding, and NotifyOnValidationError
causes an event to be raised when a validation error occurs.
The XAML data-binding system performs the following three actions during assignment of a source object property:
Conversion of the target DependencyProperty
value using an IValueConverter
. This occurs if the target’s binding has its ValueConverter
set.
Type conversion of the result of step 1 to the source property type.
Assignment of the result of step 2 to the source property, and detection and handling of exceptions raised in the source’s property set accessor.
The validation and assignment of a source property is explored in greater detail in Figure 26.1, which is based on Alexander Jung’s diagram at http://ajdotnet.wordpress.com/2010/02/28/understanding-validation-in-silverlight/.
The following list refers to numbered items in Figure 26.1 and describes each step performed by the data-binding system:
1. The change event is raised for the target’s DependencyProperty
. This event is subscribed to by the target’s BindingExpression
for the DependencyProperty
. When the FrameworkElement
’s property is changed, the BindingExpression
’s TargetPropertyChanged
method is called. The BindingExpression
then calls its own UpdateValue
method.
2. If there is a ValueConverter
defined for the binding, its ConvertBack
method is called. If an exception is raised in the ConvertBack
method, it is not handled and must be handled by the Application.UnhandledException
event handler, or the app exits.
3. An internal IValueConverter
, called DynamicValueConverter
, uses a TypeConverter
to convert the target value to the source type. The DynamicValueConverter
comes into play when, for example, a TextBox.Text
string value needs to be converted to an int
value. During conversion, noncritical Exceptions
are treated as validation errors. Critical Exceptions
are described in a later section.
4. The property setter is called using the result from the TypeConverter
. Again, if a noncritical exception is raised, it is treated as a validation error. Be mindful that if the property setter raises the PropertyChanged
event, and an event handler throws an Exception
, it results in a validation error.
5. The BindingExpression
class uses the static Validation
class to assign validation errors for the FrameworkElement
.
6. The Validation
class records validation information about a FrameworkElement
using the DependencyProperty
’s Validation.ErrorsProperty
and Validation.HasErrorProperty
. After the error has been set, the FrameworkElement
is prompted to display the error. This is normally done by transitioning the VisualState
of the control to an invalid state. We look at displaying validation errors, using VisualState
and the VisualStateManager
, later in this chapter.
7. If the binding has been set to notify of validation errors, discussed further in the following section, the BindingValidationError
event is raised.
Note
IValueConverters
are unable to participate in input validation because if an IValueConverter
throws an exception, it is rethrown by the BindingExpression
.
18.118.32.222