Incorporating Group Validation

,

In the previous example, you saw how the ViewModelBase.IsComplete method is used to trigger validation of a viewmodel. This section looks at extending the validation to set control-enabled states based on the presence of validation errors and at hiding validation errors until the user has had a chance to fill out the form.

Before proceeding, you may want to briefly review the section “Performing Group Validation” earlier in the chapter, and in particular Figure 26.7.

The SendEmailViewModel in the downloadable sample code is a more complex example of asynchronous input validation. In it, the sendEmailCommand is prevented from executing if it is already in execution or if the form is invalid.

When SendEmailView is first displayed, the Send button is enabled and no validation errors are displayed (see Figure 26.14).

Image

FIGURE 26.14 SendEmailView page. The Send button is enabled and no validation errors are shown, even though the form is not complete.

When the Send button is tapped, the viewmodel is validated. If invalid, the Send button is disabled (see Figure 26.15).

Image

FIGURE 26.15 SendEmailView page. The Send button is disabled after the form is deemed incomplete.

The Send button is bound to the viewmodel’s ICommand named SendEmailCommand, as shown:

<Button Content="Send"
        Command="{Binding SendEmailCommand}" />

Evaluation of whether the command can execute depends on the following criteria:

Image If the command is in execution, it cannot be executed.

Image If an attempt to execute the command has not occurred before, it can be executed.

Image If the viewmodel has validation errors, it cannot be executed.

SendEmailCommand is instantiated in the viewmodel constructor, as shown:

sendEmailCommand = new DelegateCommand(arg => SendEmail(),
                         arg => !sending && (!sendAttempted || !HasErrors));

The SendEmail method passes three Lambda expressions to the ViewModelBase class’s IsComplete method (see Listing 26.6). The first action is performed if the form is deemed complete, in which case an EmailComposeTask is used to dispatch the email. The second action is performed if the form is not complete, and the third displays a warning message if an error is raised.

LISTING 26.6. SendEmailViewModel.Send Method


void SendEmail()
{
    if (sending)
    {
        return;
    }

    try
    {
        sending = sendAttempted = true;
        Message = string.Empty;
        RefreshCommands();
        IsComplete(() =>
                    {
                        sending = false;
                        EmailComposeTaskAdapter task = getEmailTaskAdapter();
                        task.Body = body;
                        task.Cc = cc;
                        task.Subject = subject;
                        task.To = to;
                        task.Show();
                    },
                    () =>
                    {
                        sending = false;
                        RefreshCommands();
                    },
                    obj =>
                    {
                        sending = false;
                        RefreshCommands();
                        string errorMessage = obj != null
                                    ? obj.Message : string.Empty;
                        Message = "Unable to send email: "
                                    + errorMessage;
                    });
    }
    catch (Exception ex)
    {
        sending = false;
        Message = "Unable to send email: " + ex.Message;
    }
}


A call to RefreshCommands raises the CanExecuteChanged event of the command, which in turn sets the IsEnabled property of the button:

void RefreshCommands()
{
    sendEmailCommand.RaiseCanExecuteChanged();
}

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

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