Baba
Baba

Reputation: 2209

xamarin forms behavior : Allow only strings in an entry and not numbers

I am using the code below to disallow users from typing strings in an entry that accepts numbers. How can I reverse this for an entry that should accept strings alone and not numbers.

            private static void OnEntryTextChanged(object sender, TextChangedEventArgs args) {

                if(!string.IsNullOrWhiteSpace(args.NewTextValue)) { 
                    bool isValid = args.NewTextValue.ToCharArray().All(IsDigit); //Make sure all characters are numbers

                    ((Entry)sender).Text = isValid ? args.NewTextValue : args.NewTextValue.Remove(args.NewTextValue.Length - 1);
                }
            }

            /// <summary>
            /// Check to see if a character is a digit.
            /// </summary>
            /// <param name="c">The character to check.</param>
            /// <returns><c>true</c> if the character is between <c>0</c> and <c>9</c>.</returns>
            private static bool IsDigit(char c) {
                if(c >= 48) {
                    return c <= 57;
                }

                return false;
            }

Upvotes: 0

Views: 2886

Answers (1)

Wilson Vargas
Wilson Vargas

Reputation: 2899

You should use a regular expression for that. This regular expression only allows letters:

^[a-zA-Z]+$

Now in your method you should write like this:

const string numberRegex = @"^[a-zA-Z]+$";
private static void OnEntryTextChanged(object sender, TextChangedEventArgs args) 
{
    if(!string.IsNullOrWhiteSpace(args.NewTextValue)) 
    { 
       IsValid = (Regex.IsMatch(args.NewTextValue, numberRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
       ((Entry)sender).Text = IsValid ? args.NewTextValue : args.NewTextValue.Remove(args.NewTextValue.Length -1);       
    }
}

I don't know if your Behavior is correct but you can create it like this:

public class EntryValidatorBehavior: Behavior<Entry>
{
    const string numberRegex = @"^[a-zA-Z]+$";

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

    public 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.TextChanged += HandleTextChanged;
    }

    void HandleTextChanged(object sender, TextChangedEventArgs e)
    {
        IsValid = (Regex.IsMatch(e.NewTextValue, numberRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
        ((Entry)sender).Text = IsValid ? e.NewTextValue : e.NewTextValue.Remove(e.NewTextValue.Length -1);
    }

    protected override void OnDetachingFrom(Entry bindable)
    {
        bindable.TextChanged -= HandleTextChanged;
    }
}

And in your View (xaml file) like this:

<Entry Placeholder="Paste here your value" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
    <Entry.Behaviors>
             <validator:EntryValidatorBehavior x:Name="numberValidator"/>
    </Entry.Behaviors>
</Entry>

Upvotes: 1

Related Questions