3

I'm using the .net Community Toolkit and MVVM to create simple page with a few form fields. I would like to display validation errors next to each field - e.g. using a Label control that has its visibility set to true if there is an error with the respective field, and the value set to the error message from the ViewModel.

At present, I can see that the HasErrors property is set to true if there's a problem with one of the fields, however I cannot see how to correctly 'pass' the validation errors to the UI, and make the label visible (hence I've left the IsVisible and Text properties empty below).

The key bits of my code setup are:

public partial class MyViewModel : ObservableValidator
{
    [ObservableProperty]
    [NotifyDataErrorInfo]
    [MinLength(3, ErrorMessage = "Flight number is required.")]
    [Required(ErrorMessage = "Flight number is required.")]
    private string flightNumber;

    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "Airline is required.")]
    private string airline;


    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "Destination is required.")]
    private string destination;


    [RelayCommand]
    private void Submit()
    {
        ValidateAllProperties();

        if (!HasErrors)
        {
            // Allow user to progress
        }
    }

    
}

And the XAML is:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewmodel="clr-namespace:TestApp.ViewModels"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="TestApp.Views.TestPage"
             Title="Test">
   <ContentPage.Resources>
          <Style x:Key="InvalidEntryStyle"
                 TargetType="Entry">
                 <Setter Property="TextColor"
                         Value="Red"/>
          </Style>
          <Style x:Key="ValidEntryStyle"
                 TargetType="Entry">
                 <Setter Property="TextColor"
                         Value="Green"/>
          </Style>

   </ContentPage.Resources>

   <StackLayout Padding="20"
                Spacing="10">

          <!-- Flight Number Entry -->
          <Entry
                 Placeholder="Flight Number"
                 Text="{Binding FlightNumber}"
                 PlaceholderColor="Gray"/>

          <!-- Airline Entry -->
          <Entry Placeholder="Airline"
                 Text="{Binding Airline}"
                 PlaceholderColor="Gray"/>
          <Label Text=""
                 TextColor="Red"
                 IsVisible=""/>

          <!-- Destination Entry -->
          <Entry Placeholder="Destination"
                 Text="{Binding Destination}"
                 PlaceholderColor="Gray"/>
          <Label Text=""
                 TextColor="Red"
                 IsVisible=""/>

          <!-- Submit Button -->
          <Button Text="Submit"
                  Command="{Binding SubmitCommand}"/>
   </StackLayout>

</ContentPage>
5
  • Since you followed the easy path, you will not get better results, the hard way is to create a Custom Control as a Container for Entry or other controls, and that Custom Control have an icon and label to show error message with red color and so on, finally, you bind it with your Validation on the ViewModel, I'm sorry I did not create it yet for MAUI to share it with you. Commented Jun 8, 2024 at 22:57
  • 1
    Have a look here learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/… and this Video youtube.com/watch?v=sNter79tWb4 Commented Jun 8, 2024 at 23:16
  • 1
    If the goal is to show the user something is wrong with their input, I think using event triggers is a decent way to do this \before the submit button is even pressed: learn.microsoft.com/en-us/dotnet/maui/fundamentals/… Commented Jun 9, 2024 at 10:05
  • 1
    @AlJohn yours was the approach that sent me in the right direction. I ended up using a data trigger to hide/show a label based on the status of a TextValidationBehavior Commented Jun 9, 2024 at 14:53
  • @MarkC80 Glad it helped! Feel free to answer your question with the TextValidationBehavior approach you used. Commented Jun 9, 2024 at 16:59

1 Answer 1

1

Here's an approach that I found got me 95% of the way toward what I wanted:

            <Entry
                Grid.Row="1"
                Grid.Column="0"
                x:Name="FlightOrigin"
                Text="{Binding DepartureAirport }"
                SemanticProperties.HeadingLevel="Level2"
                FontSize="Medium"
                HorizontalOptions="FillAndExpand"
                HorizontalTextAlignment="Start"
                MaxLength="3"
                TextTransform="Uppercase"
                Placeholder="e.g. LHR"
                IsSpellCheckEnabled="False"
                IsTextPredictionEnabled="False"
                VerticalOptions="Start">
                <Entry.Behaviors>
                    <toolkit:TextValidationBehavior
                        x:Name="DepartureAirportValidator"
                        InvalidStyle="{StaticResource InvalidEntryStyle}"
                        Flags="ValidateOnValueChanged"
                        MaximumLength="3"/>
                </Entry.Behaviors>
            </Entry>
            <Label Grid.Row="2"
                   Grid.Column="0"
                   x:Name="DepartureAirportInvalid"
                   Text="Please choose a valid airport."
                   TextColor="Red"
                   FontSize="Small">
                <Label.Triggers>
                    <DataTrigger TargetType="Label"
                                 Binding="{Binding Source={x:Reference DepartureAirportValidator},
                                       Path=IsNotValid}"
                                 Value="True">
                        <Setter Property="IsVisible"
                                Value="True"/>
                    </DataTrigger>

                </Label.Triggers>
            </Label>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.