An Example of Asynchronous Input Validation

,

The downloadable sample code contains a number of examples of asynchronous input validation. The simplest is located in the AsyncValidationViewModel class.

The AsyncValidationView contains two string properties that are required to be non-null or whitespace strings (see Figure 26.12).

Image

FIGURE 26.12 AsyncValidationView page.

When either of the two properties is set to an empty or whitespace string, a data validation error is created for that property. This validation occurs when the user modifies the text or when the Submit button is tapped (see Figure 26.13).

Image

FIGURE 26.13 The Validated String 1 form field is deemed invalid.

The two TextBox controls are each bound to a property in the viewmodel, as shown in the following excerpt:

<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,60,12,0">
    <TextBlock Text="Validated String 1"
                Style="{StaticResource PhoneTextTitle3Style}" />
    <TextBox Text="{Binding ValidatedString1, Mode=TwoWay,
                                NotifyOnValidationError=True}"
                Style="{StaticResource ValidatingTextBoxStyle}" />
    <TextBlock Text="Validated String 2"
                Style="{StaticResource PhoneTextTitle3Style}" />
    <TextBox Text="{Binding ValidatedString2, Mode=TwoWay,
                                NotifyOnValidationError=True}"
                Style="{StaticResource ValidatingTextBoxStyle}" />
    <StackPanel Orientation="Horizontal">
        <Button Content="Submit"
            Command="{Binding SubmitCommand}"
            Width="144" Height="75" HorizontalAlignment="Left" />
        <controls:ValidationSummary />
    </StackPanel>
    <TextBlock Text="{Binding Message}"
                Style="{StaticResource PhoneTextNormalStyle}" />
</StackPanel>

The submit Button is bound to the viewmodel’s SubmitCommand. The SubmitCommand is instantiated in the constructor of the AsyncValidationViewModel class, as shown in the following excerpt:

public AsyncValidationViewModel()
{
    AddValidationProperty(() => ValidatedString1);
    AddValidationProperty(() => ValidatedString2);

    submitCommand = new DelegateCommand(
        delegate
        {
            IsComplete(
                () => Message = "Data Submitted!",
                () => Message = string.Empty,
                obj => Message = "An error occured: " + obj.Message);
        });
}

When the button is pressed, the SubmitCommand calls the IsComplete method of the ViewModelBase class, which calls the DataErrorNotifier.IsComplete method with the same signature. Recall that the IsComplete method has the following three parameters:

Image An Action to perform if there are no validation errors.

Image An Action to perform if there are validation errors.

Image A Func to perform if an exception is raised and the validation process fails.

The IsComplete method causes the overridden BeginValidation method of the AsyncValidationViewModel class to be called. Asynchronous behavior is simulated by calling a private Validate method using a thread from the ThreadPool. In a less trivial application, we could imagine that this call could be to a web service, for example.

public override void BeginValidation(string memberName, object value)
{
    try
    {
        /* Perform validation asynchronously. */
        ThreadPool.QueueUserWorkItem(state => Validate(memberName, value));
    }
    catch (Exception ex)
    {
        OnValidationComplete(
            new ValidationCompleteEventArgs(memberName, ex));
    }
}

As previously stated, it is imperative that the ValidationComplete event is raised no matter what the outcome of the validation activity. Therefore, the validation logic is wrapped in a try-catch block, so that if an exception occurs, the ValidationComplete event is still raised, as shown in the following excerpt:

void Validate(string propertyName, object value)
{
    try
    {
        IEnumerable<DataValidationError> errors
            = GetPropertyErrors(propertyName, value);
        if (errors != null && errors.Count() > 0)
        {
            OnValidationComplete(
                new ValidationCompleteEventArgs(propertyName, errors));
        }
        else
        {
            OnValidationComplete(
                new ValidationCompleteEventArgs(propertyName));
        }
    }
    catch (Exception ex)
    {
        OnValidationComplete(
            new ValidationCompleteEventArgs(propertyName, ex));
    }
}

If either of the viewmodel’s string properties fails validation, a DataValidationError for the property is added to the list of validation errors for that property.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.103.229