Xamarin Forms Password and Confirm Password Validation

11,746

Solution 1

https://forums.xamarin.com/discussion/34695/xaml-how-do-you-pass-a-control-view-reference-into-a-behavior

This will help you. You will use Compare Validator behavior for this as following.

<behaviors:CompareValidator x:Name="ComparePasswordsValidator" 
        CompareToEntry="{Binding Source={x:Reference PasswordEntry}}" /> 

Finally The Solution:

XAML-

<Entry x:Name="password" Placeholder="New Password" IsPassword="true">
    <Entry.Behaviors>
        <local:RequiredValidatorBehavior x:Name="passwordValidator"/>   
    </Entry.Behaviors>
</Entry>
<Entry x:Name="confirmPassword" Placeholder="Confirm Password" IsPassword="true">
    <Entry.Behaviors>
        <local:ConfirmPasswordBehavior x:Name="confirmPasswordBehavior" CompareToEntry="{Binding Source={x:Reference password}}" />
    </Entry.Behaviors>
</Entry>

BEHAVIOR-

    public class ConfirmPasswordBehavior : Behavior<Entry>
    {
        static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(ConfirmPasswordBehavior), false);
        public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;

        public static readonly BindableProperty CompareToEntryProperty = BindableProperty.Create("CompareToEntry", typeof(Entry), typeof(ConfirmPasswordBehavior), null);

        public Entry CompareToEntry
        {
            get { return (Entry)base.GetValue(CompareToEntryProperty); }
            set { base.SetValue(CompareToEntryProperty, value); }
        }
        public bool IsValid
        {
            get { return (bool)base.GetValue(IsValidProperty); }
            private set { base.SetValue(IsValidPropertyKey, value); }
        }
        protected override void OnAttachedTo(Entry bindable)
        {
            bindable.TextChanged += HandleTextChanged;
            base.OnAttachedTo(bindable);
        }
        protected override void OnDetachingFrom(Entry bindable)
        {
            bindable.TextChanged -= HandleTextChanged;
            base.OnDetachingFrom(bindable);
        }
        void HandleTextChanged(object sender, TextChangedEventArgs e)
        {
            var password = CompareToEntry.Text;
            var confirmPassword = e.NewTextValue;
            IsValid = password.Equals (confirmPassword);
        }
    }

Solution 2

I've make some changes on Punnet answer:

First, to fix the null exception on HandleTextChanged that was thrown when the comparable string was null

    void HandleTextChanged(object sender, TextChangedEventArgs e)
    {
        string theBase = CompareToEntry.Text;
        string confirmation = e.NewTextValue;
        // here is the change
        IsValid = (bool)theBase?.Equals(confirmation);

        ((Entry)sender).TextColor = IsValid ? Color.Green : Color.Red;
    }

And the second was to check if the comparable string was changed after the validation becomes true.

    void baseValue_changed(object sender, TextChangedEventArgs e)
    {
        IsValid = (bool)((Entry)sender).Text?.Equals(thisEntry.Text);
        thisEntry.TextColor = IsValid ? Color.Green : Color.Red;
    }

So the new code become

public class ComparisonBehavior : Behavior<Entry>
{
    private Entry thisEntry;

    static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(ComparisonBehavior), false);
    public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;

    public static readonly BindableProperty CompareToEntryProperty = BindableProperty.Create("CompareToEntry", typeof(Entry), typeof(ComparisonBehavior), null);

    public Entry CompareToEntry
    {
        get { return (Entry)base.GetValue(CompareToEntryProperty); }
        set
        {
            base.SetValue(CompareToEntryProperty, value);
            if (CompareToEntry != null)
                CompareToEntry.TextChanged -= baseValue_changed;
            value.TextChanged += baseValue_changed;
        }
    }

    void baseValue_changed(object sender, TextChangedEventArgs e)
    {
        IsValid = ((Entry)sender).Text.Equals(thisEntry.Text);
        thisEntry.TextColor = IsValid ? Color.Green : Color.Red;
    }


    public bool IsValid
    {
        get { return (bool)base.GetValue(IsValidProperty); }
        private set { base.SetValue(IsValidPropertyKey, value); }
    }
    protected override void OnAttachedTo(Entry bindable)
    {
        thisEntry = bindable;

        if (CompareToEntry != null)
            CompareToEntry.TextChanged += baseValue_changed;

        bindable.TextChanged += HandleTextChanged;
        base.OnAttachedTo(bindable);
    }

    protected override void OnDetachingFrom(Entry bindable)
    {
        bindable.TextChanged -= HandleTextChanged;
        if (CompareToEntry != null)
            CompareToEntry.TextChanged -= baseValue_changed;
        base.OnDetachingFrom(bindable);
    }

    void HandleTextChanged(object sender, TextChangedEventArgs e)
    {
        string theBase = CompareToEntry.Text;
        string confirmation = e.NewTextValue;
        IsValid = (bool)theBase?.Equals(confirmation);

        ((Entry)sender).TextColor = IsValid ? Color.Green : Color.Red;
    }
}

Solution 3

I have developed custom control to validate our model using data annotation method.

Here is project url.

https://github.com/MaulikParmar/XamarinForms/tree/master/ValidationDemo

It is not working for window 8.1 phone.

Here is youtube url for project description and how to use this control more effectively.

https://www.youtube.com/watch?v=eEi-Oky4U08

Share:
11,746
Manik Arora
Author by

Manik Arora

https://in.linkedin.com/pub/manik-arora/4a/281/950 Full-Stack Application Developer, Programming Worm, Technological Freak, Internet Nut, Self Proclaimed Disk Jockey, Sun Hater, Life Liver, to be continued... #SOreadytohelp

Updated on June 04, 2022

Comments

  • Manik Arora
    Manik Arora about 2 years

    I have a Xamarin Forms application in which I have a registration form in which I need to validate Password and Confirm Password fields should be same.

    Is there any way to implement this using Xamarin Behaviour?

    I have already implemented Xamarin Behaviour for Required Field validation and Email Regex validation like this below-

    public class RequiredValidatorBehavior : Behavior<Entry>
        {
            static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(RequiredValidatorBehavior), false);
            static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;
    
            public bool IsValid
            {
                get { return (bool)base.GetValue(IsValidProperty); }
                private set { base.SetValue(IsValidPropertyKey, value); }
            }
    
            protected override void OnAttachedTo(Entry bindable)
            {
                bindable.Unfocused += HandleFocusChanged;
                base.OnAttachedTo(bindable);
            }
            protected override void OnDetachingFrom(Entry bindable)
            {
                bindable.Unfocused -= HandleFocusChanged;
                base.OnDetachingFrom(bindable);
            }
            void HandleFocusChanged(object sender, FocusEventArgs e)
            {
                IsValid = !string.IsNullOrEmpty (((Entry)sender).Text);
            }
        }
    

    Implementation of Behaviour in XAML Content Page-

    <Entry x:Name="password" Placeholder="New Password">
        <Entry.Behaviors>
            <local:RequiredValidatorBehavior x:Name="passwordValidator"/>   
        </Entry.Behaviors>
    </Entry>
    

    The problem is - I am new in Xamarin development and have no idea how can I get the value of both Password and Confirm Password fields in Behaviour so that I can compare them. I do not wish to compare them on click of button when the form is submitted, fields should be compared while the user is typing in the fields. Any code, help or guidance is appreciable.