Ignore keypress event

I want to restrict my input to alphabetical characters. I currently detect TextChanged event and change the binding to e.OldText. This is not a great way of doing things and I would rather block the keypress at source, events like Keypress.Handle() in WPF make this very easy:

private void SearchTextChanged(TextChangedEventArgs e)
    {
        if (!string.IsNullOrEmpty(e.NewTextValue))
        {
            if (!Regex.IsMatch(e.NewTextValue, "^[a-zA-Z ]*$"))
            {
                SearchText = e.OldTextValue;
                return;
            }
        }
}

Answers

  • ColeXColeX Member, Xamarin Team Xamurai
    edited September 11

    You could move the logic into Behavior and attach it to Entry .

    Create custom Behavior

        public class AlphabetValidator : Behavior
            {
    
                const string regex = @"^[a-zA-Z]*$";
    
                static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(regex), 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(BindableObject bindable)
                {
                    ((Entry)bindable).TextChanged += HandleTextChanged;
                }
    
                protected override void OnDetachingFrom(BindableObject bindable)
                {
                    ((Entry)bindable).TextChanged -= HandleTextChanged;
                }
    
                void HandleTextChanged(object sender, TextChangedEventArgs e)
                {
                    IsValid = (Regex.IsMatch(e.NewTextValue, regex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
                    ((Entry)sender).Text = IsValid ? e.NewTextValue : e.OldTextValue;
                }
    
            }
    

    Attach it to Entry

             public Page5()
            {
                InitializeComponent();
    
                Entry entry = new Entry
                {
                    Behaviors = { new AlphabetValidator { } }
                };    
                Content = entry;
            }
    

    Also , check Validation in Enterprise Apps .

  • robiharidrobiharid Member ✭✭
    edited September 12

    @ColeX said:
    You could move the logic into Behavior and attach it to Entry .

    Create custom Behavior

        public class AlphabetValidator : Behavior
            {
        
                const string regex = @"^[a-zA-Z]*$";
        
                static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(regex), 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(BindableObject bindable)
                {
                    ((Entry)bindable).TextChanged += HandleTextChanged;
                }
        
                protected override void OnDetachingFrom(BindableObject bindable)
                {
                    ((Entry)bindable).TextChanged -= HandleTextChanged;
                }
        
                void HandleTextChanged(object sender, TextChangedEventArgs e)
                {
                    IsValid = (Regex.IsMatch(e.NewTextValue, regex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
                    ((Entry)sender).Text = IsValid ? e.NewTextValue : e.OldTextValue;
                }
               
            }
    

    Attach it to Entry

             public Page5()
            {
                InitializeComponent();
    
                Entry entry = new Entry
                {
                    Behaviors = { new AlphabetValidator { } }
                };    
                Content = entry;
            }
    

    Also , check Validation in Enterprise Apps .

    This seems like a lot of work for what is one line in WFP... 'KeyPress.Handle()"

    Do you add the behaviour as a style in the Resource Dictionary, and then set:

    <Entry Placeholder="Enter a System.Double" Style="{StaticResource NumericValidationStyle}">
    
Sign In or Register to comment.