Home > Enterprise >  Xamarin Community Toolkit input validation is true when BindingContext is set
Xamarin Community Toolkit input validation is true when BindingContext is set

Time:12-20

When the BindingContext is set, IsValid sets IsLastnameValid and IsFirstnameValid to true even if the required parameters are not correct. And I don't understand why.

XMAL code

<StackLayout>
    <Entry Placeholder="Lastname" Text="{Binding Lastname}">
        <Entry.Behaviors>
            <xct:TextValidationBehavior MinimumLength="3" MaximumLength="10"
                IsValid="{Binding IsLastnameValid}"/>
        </Entry.Behaviors>
    </Entry>

    <Entry Placeholder="Firstname" Text="{Binding Firstname}">
        <Entry.Behaviors>
            <xct:TextValidationBehavior MinimumLength="3" MaximumLength="10"
                IsValid="{Binding IsFirstnameValid}"/>
        </Entry.Behaviors>
    </Entry>

    <Button Text="Save" Clicked="OnSave">
        <Button.IsEnabled>
            <MultiBinding  Converter="{StaticResource BooleanAndConverter}">
                <Binding Path="IsLastnameValid"/>
                <Binding Path="IsFirstnameValid"/>
            </MultiBinding>
        </Button.IsEnabled>
    </Button>
</StackLayout>

CS Code

public partial class MainPage : ContentPage
{
    private UserViewModel _userViewModel;

    public MainPage()
    {
        InitializeComponent();
        _userViewModel = new UserViewModel(false, false);
        BindingContext = _userViewModel;
    }

    private void OnSave(object sender, EventArgs e)
    {
        Console.WriteLine("[User View Model Firstname] : "   _userViewModel.Firstname   "  "   _userViewModel.IsFirstnameValid);
        Console.WriteLine("[User View Model Lastname] : "   _userViewModel.Lastname   "  "   _userViewModel.IsLastnameValid);
    }
}

ViewModel Code I'm using the Nuget Package PropertyChanged.Fody

[AddINotifyPropertyChangedInterface]
public class UserViewModel
{
    public UserViewModel(bool isLastnameValid, bool isFirstnameValid)
    {
        IsLastnameValid = isLastnameValid;
        IsFirstnameValid = isFirstnameValid;
    }

    public string Lastname { get; set; }
    public string Firstname { get; set; }
    public bool IsLastnameValid { get; set; }
    public bool IsFirstnameValid { get; set; }
}

Thanks for your help :)

Edited to show the converter code

public class BooleanAndConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {

        if (values.Any(value => value == null))
        {
            return false;
        }

        var result = values.OfType<IConvertible>().All(System.Convert.ToBoolean);
        return result;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("BooleanAndConverter is a OneWay converter.");
    }
}

CodePudding user response:

This code works in my test repo (see link in my comment above):

<Entry Placeholder="Lastname" Text="{Binding Lastname}">
    <Entry.Behaviors>
        <xct:TextValidationBehavior MinimumLength="3" MaximumLength="10"
         Flags="ValidateOnAttaching, ValidateOnValueChanging" IsValid="{Binding IsLastnameValid}"/>
    </Entry.Behaviors>
</Entry>

The only change from yours is the addition of attribute

Flags="ValidateOnAttaching, ValidateOnValueChanging"

Given that, pressing Save button results in debug output with "false" for IsValid.


EDITTED: If you set flags manually, then the default flags don't apply. So need to list all desired flags. I've changed the code snippet above.

See ValidationFlags enum.

You might also want to include , ValidateOnUnfocusing. This checks again when user leaves that control (e.g. clicks on another control).

  • Related