Is there a way to get a event fired when delete is pressed when an entry is empty in xamarin forms

3.2k views Asked by At

So i have four different entries, which acts as a pin input holder, and what i'm trying to do is , basically each entry when backspace is pressed should go to the previous entry considering the entry on which the backspace was pressed is empty.

I tried doing it in Renderer but it doesn't fire anything when its empty, same goes for TextChanged

What i was trying to do was a small hack ,where in i tried to put " ", that is a space in all the entries while initializing, and when a user tried to put something i would check the old value and new value, and replace it, but the problem seems to be when i navigate to the second entry and lets say i press backspace, then the i should be able to go the first entry which is something i'm not able to figure out how

below is a small snippet of what i was trying to do, but it has some issues, any inputs would be helpful

private void secondEntry_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (e.OldTextValue == null && !e.NewTextValue.Equals(" "))
            {
                Entry_Second.Text = e.NewTextValue;
                Entry_Third.Focus();
            }
            else if (e.NewTextValue == "")
            {
                Entry_Second.Text = " ";
            }
            else
            {
                Entry_Second.Focus();
            }
}
3

There are 3 answers

12
Pooja Kamath On BEST ANSWER

In Xamarin.Android , you can try to handle the edit text key press event. Keycode is Keycode.Back when the delete button is pressed on a keyboard and handle the event accordingly.

          editText.KeyPress += (object sender, View.KeyEventArgs e) => {
                e.Handled = false;
                if (e.Event.Action == KeyEventActions.Down && e.KeyCode == Keycode.Back)
                {
                    //your logic here
                    e.Handled = true;
                }
            };

In Xamarin.iOS

You can try overriding the DeleteBackward method in the custom text field (BackDeleteEventTextField) and call a custom event OnDeleteBackwardKeyPressed.

In the custom renderer you can override the text field with your custom text field in on element changed method

   var textField = new BackDeleteEventTextField();

and handle the custom event OnDeleteBackwardKeyPressed

textField.OnDeleteBackwardKeyPressed += (sender, a) =>
        {
           //handle the back key pressed event
        };

In Xamarin.Android :

In the custom renderer you can handle the key press event and look for the Keycode.Back

((EditText)this.Control).KeyPress += (object sender, View.KeyEventArgs even) => { 
        even.Handled = false; 
       if (even.Event.Action == KeyEventActions.Down && even.KeyCode ==         Keycode.Back) 
       { 
          //your logic here even.Handled = true;
        } 

};

Update

Elaborating for xamarin.iOS using forms.

Step 1: Create a custom entry class and create a delegate to handle the back button press

public class CustomEntry: Entry
{
    public delegate void BackButtonPressEventHandler(object sender, EventArgs e);

    public event BackButtonPressEventHandler OnBackButton;

    public CustomEntry() { }

    public void OnBackButtonPress() 
    {
        if (OnBackButton!= null)
        {
            OnBackButton(null, null);
        }
    }
}

Step 2 :Within the custom renderer namespace , create a custom text field class.

[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Origination.iOS.Renderers
{
    public class CustomTextField: UITextField
    {
    }
}

Step 3: Within the custom text field, create a event and delegate to handle the delete button click.

 public class CustomTextField: UITextField
    {
        // A delegate type for hooking up change notifications.
        public delegate void DeleteBackwardKeyEventHandler(object sender, EventArgs e);

        // An event that clients can use to be notified whenever the
        // elements of the list change.
        public event DeleteBackwardKeyEventHandler OnDeleteBackwardKey;


        public void OnDeleteBackwardKeyPressed()
        {
            if (OnDeleteBackwardKey != null)
            {
                OnDeleteBackwardKey(null, null);
            }
        }

        public override void DeleteBackward()
        {
            base.DeleteBackward();
            OnDeleteBackwardKeyPressed();
        }
}

Step 4 :Within the custom renderer name space, Create custom renderer class.

 public class CustomEntryRenderer: EntryRenderer, IUITextFieldDelegate
 {
 }

Step 5:Within the custom renderer's OnElementChanged method create a text field of the custom text field type.

Step 6: Handle the custom text field delete event by passing it to the custom entry back button event handler.

Step 7: Assign the custom text field object to native control.

 protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
            {
                if (Element == null) 
                {
                    return;
                }

                var entry = (CustomEntry)Element;
                var textField = new CustomTextField();

               textField.EditingChanged += OnEditingChanged;
                textField.OnDeleteBackwardKey += (sender, a) =>
                {
                    entry.OnBackButtonPress();
                };

                SetNativeControl(textField);

                base.OnElementChanged(e);
            }

step 8 : Add the editing changed handler

  IElementController ElementController => Element as IElementController;

 void OnEditingChanged(object sender, EventArgs eventArgs)
        {
            ElementController.SetValueFromRenderer(Entry.TextProperty, Control.Text);
        }
1
Bruno Caceiro On

In order to validate if the string is empty you can just:

(string.IsNullOrWhiteSpace(value))

After that, is just a matter of focus and unfocus the Entries that you require.

2
NappyCoder On

I found the first example for Xamarin.Android in the accepted answer worked for me with the exception of changing KeyCode.Back to KeyCode.Del to capture the backspace keypress.