3

I have a simple form where user add email:

                       <Entry Placeholder="Email" Text="{Binding Email}">
                            <Entry.Behaviors>
                                <xct:MultiValidationBehavior >
                                    <xct:EmailValidationBehavior  Flags="ValidateOnUnfocusing"/>
                                </xct:MultiValidationBehavior>
                            </Entry.Behaviors>
                        </Entry>

And have a button:

     <Button Text="Send" Command="{Binding LoadSendRegistrationCommand}" TextColor="#07987f"  BackgroundColor="#eeeeee"  Margin="0,10,0,10"></Button>

When click on button how to check and return message if email is not valid?

Rajzer
  • 1,174
  • 11
  • 24

2 Answers2

11

There's (as always) multiple ways to do this. If you just want to do this from your code-behind without MVVM/data-binding you still have two options.

Since you're using the MultiValidationBehavior you could give that an x:Name="myValidation" attribute and access that from your code-behind. You will then be able to do:

1. Through MultivalidationBehavior

if (!myValidation.IsValid)
{
    // Somehow show the errors, this needs some extra code, but you get the idea :)
    DisplayAlert("Error", myValidation.Errors, "OK");
}

Additionally you probably want to specify the MultivalidationBehavior.Error property on the EmailValidationBehavior, i.e.:

<xct:EmailValidationBehavior xct:MultiValidationBehavior.Error="Email not valid" Flags="ValidateOnUnfocusing"/>

2. Through EmailValidationBehavior

You can also do it with the EmailValidationBehavior directly. For this add an x:Name="myEmailValidation" attribute to your EmailValidationBehavior and you can access it in your code-behind:

if (!myEmailValidation.IsValid)
{
    DisplayAlert("Error", "Email not valid", "OK");
}
else
{
    DisplayAlert("Success", "All valid!", "OK");
}

3. Through data-binding

I actually noticed while typing all this that you did use data-binding with the Command for that button and the value of the email. In that case, you can also bind to the IsValid property on either the EmailValidationBehavior or MultiValidationBehavior and then toggle some UI element to visible or not depending on that.

For this we need to do a couple of things. I will focus on the EmailValidationBehavior, I trust that you can figure it out for the MultiValidationBehavior one.

  1. Add the binding to your EmailValidationBehavior: <xct:EmailValidationBehavior IsValid="{Binding EmailValid}" Flags="ValidateOnUnfocusing"/>

  2. Add a backing property to the object that is in your BindingContext:

private bool emailValid;

public bool EmailValid
{
    get => emailValid;
    set
    {
        emailValid = value;
        OnPropertyChanged();
     }
}
  1. Add the UI element to indicate to the user. Of course, this could also be disabling a button or something. <Label Text="Email not valid" TextColor="Red" IsVisible="{Binding EmailValid, Converter={StaticResource invertBoolConverter}}" />

Notice that I need to also use the InvertedBoolConverter from the Toolkit to invert the value from IsValid to work with it correctly with IsVisible of the Label

  1. Add the converter
<ContentPage.Resources>
    <ResourceDictionary>
        <xct:InvertedBoolConverter x:Key="invertBoolConverter" />
    </ResourceDictionary>
</ContentPage.Resources>

That should be it :)

Working sample with all this code can be found here: https://github.com/jfversluis/XCTInputValidationCodeBehindSample

Gerald Versluis
  • 30,492
  • 6
  • 73
  • 100
  • You don't need to add the converter as a resource since it implements IMarkupExtension. – Roubachof Feb 02 '21 at 11:02
  • @GeraldVersluis hey man i watched every video on your utube channel. Keep going! My suggestion is go throughout every functionality of XCT in separate video. Have a nice day – Rajzer Feb 02 '21 at 14:05
  • 1
    Thanks @Rajzer! appreciate it! There will be a lot more XCT videos, I think this might be one of them :) – Gerald Versluis Feb 02 '21 at 15:02
  • 1
    It worked good. However, the Flags="ValidateOnUnfocusing" does not trigger it when it is requested. For example, if we need to trigger the validation behaviors when clicking a button, that won't be possible. Neither from an ViewModel. – vhugo May 06 '21 at 15:34
  • As a workaround to my previous comment you can do the following on the click button event and on the view model you must at least validate manually: EmailValidator.ForceValidate(); – vhugo May 06 '21 at 15:45
  • 1
    @acido It still doesn't work for me even when using `ForceValidate();` – Hackmodford Dec 01 '21 at 20:30
  • 1
    @acido I discovered I can call `Unfocus()` on the entry to force the validation – Hackmodford Dec 01 '21 at 23:04
  • 1
    I also discovered you must also call ForceValidate – Hackmodford Dec 01 '21 at 23:25
0

First: I do no think it is smart to use "ValidateOnUnfocusing". You are literally hoping that someone will focus it, edit it, and unfocus it after that, to fire that validation.

If you change that entry without focusing it. Or if you change it, and then do something, before you unfocus it, the validation would not have fired. So this "IsValid" property will not be correct.

Second: If you do not mind the difference in the behavior, I can recommend "ValidateOnValueChanged".

This way, the unfocusing problem is dealt with. You have to deal with the problem when someone has not entered anything. Initializing the property in your code will solve this. (Email = "";)

Edit: If this doesn't work for you, manual validation with regex is still an option.

H.A.H.
  • 2,104
  • 1
  • 8
  • 21