WildGums/Orc.Wizard

ViewModel warnings aren't shown

Closed this issue · 12 comments

When adding a business rule/field warning to a ViewModel, it is not displayed in any way in the wizard, if there are no business rule/field errors. As an example, a field error would mark the field red and display an errors-and-warnings status bar at the top of the page.

Handling of the field warning is as follows:

internal class MyWizardPageViewModel : WizardPageViewModelBase<MyWizardPage>
{
    public MyWizardPageViewModel(MyWizardPage wizardPage) : base(wizardPage)
    {
    }

    [ViewModelToModel]
    [Range(ushort.MinValue, ushort.MaxValue, ErrorMessageResourceName = nameof(Resources.field_value_out_of_range_validation_error_message), ErrorMessageResourceType = typeof(Resources))]
    public string Port { get; set; }

    protected override void ValidateFields(List<IFieldValidationResult> validationResults)
    {
        System.ComponentModel.DataAnnotations.ValidationResult localPortIsAvailable = NetworkRelatedFieldValidation.LocalPortIsAvailable(Port, new System.ComponentModel.DataAnnotations.ValidationContext(this));

        if (localPortIsAvailable != System.ComponentModel.DataAnnotations.ValidationResult.Success)
        {
            validationResults.Add(FieldValidationResult.CreateWarning(() => Port, "Oh NO!!!"));
        }
    }
}

You should set NotifyOnValidationError and ValidateOnDataErrors on the binding.

Thank you @GeertvanHorrik,

But I think I did this already. Here is the XAML of the corresponding view.

<catel:UserControl x:Class="SetupWizard.Views.MyWizardPageView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:catel="http://catel.codeplex.com"
            mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">

    <catel:StackGrid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Label Content="{catel:LanguageBinding port_field_label}" />
        <TextBox Text="{Binding Port, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />

    </catel:StackGrid>
</catel:UserControl>

Please upload a simple repro so I can check the code.

Here is a repository: sindilevich/Orc.Wizard.Samples@74a6a88c2df744d2ef24d773113b5271681daaf6
It shows a wizard with two pages:

  • page to enter a port in
  • a summary page

The Port field has both a Range attribute for correctness check (if it's not in the 0-65,535 range, I expect a validation error displayed); and a field warning, set through the ValidateFields method. The sample application will always mark the Port with the field warning.

Note, however, the field warning isn't displayed unless there is also a field error displayed.

When I set it as error, it shows up:

image

The reason is that warnings will be allowed, where errors are not. If you want to show the errors immediately at startup (I don't recommend it), use this code in your view model:

protected override async Task InitializeAsync()
{
    DeferValidationUntilFirstSaveCall = false;

    await base.InitializeAsync();

    Validate(true);
}

@GeertvanHorrik, thank you for your explanation. I am truly do not want prevent wizard navigation because of warnings, but it would be nice if I could somehow hint the user there is a warning on the page. I'd think a yellowish highlight over a warning field (when this field doesn't have errors on it, of course), and the well-known infobar.

In that case you'll need to create your own adorner (and provide a style that uses this adorner) to show an orange rectangle. You could also return false on the first save call in case there are warnings, then the wizard won't proceed, but will show the warnings in the top bar. Then the 2nd click could still allow the user to proceed.

This being said, there isn't a solution out of the box. In some wizards we created, we ask the user whether they want to proceed with the warning using a messagebox (using IMessageService in the SaveAsync of a page).

@GeertvanHorrik, could you please elaborate on:

You could also return false on the first save call in case there are warnings, then the wizard won't proceed, but will show the warnings in the top bar. Then the 2nd click could still allow the user to proceed.

How do I do that exactly in the code (the sample repo I've created)?

@GeertvanHorrik, I was able to implement your suggestion with the 1st vs. 2nd click on navigation buttons to show the warnings: sindilevich/Orc.Wizard.Samples@5ee5fdfbf62dc6a5423420ec42e75747aad0d0f4 .

But couldn't create your own adorner (and provide a style that uses this adorner) to show an orange rectangle. How do I highlight a field after a navigation button was pressed for the first time on the page, to draw user's attention?

Creating adorners is a bit complex and will require your to restyle all controls you use on the wizard (e.g. textbox, checkbox, combobox, etc). I think the textbox / double next button is the easiest way to solve this issue.

I ended up with a warning message (via IMessageService), when user clicks on the Next button for the first time. The subsequent click on the Next button would allow the wizard continue to the next page. Any changes to fields' values would re-issue the warning message next time the Next button is clicked.

lock commented

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.