Search Unity

TextField ignore keyboard Up/Down Arrow key

Discussion in 'UI Toolkit' started by Hungweng6, Feb 14, 2020.

  1. Hungweng6

    Hungweng6

    Joined:
    Jan 7, 2014
    Posts:
    9
    Hi, for a single line TextField, it handles UpArrow like Home key and DownArrow like End key
    Is there a way to make it ignore those keyboard events?
     
  2. sebastiend-unity

    sebastiend-unity

    Unity Technologies

    Joined:
    Nov 9, 2015
    Posts:
    184
    TextFields process keys at core level. Same process as IMGUI TextFields. But you could potentially register for key events in your instance, listen to Up and Down keys and skip them, then stop propagation of the event:

    Code (CSharp):
    1. {
    2.    ...
    3.    TextField myTextField = ...;
    4.     VisualElement myTextInput = myTextField.Q("unity-text-input");
    5.     myTextInput.RegisterCallback<KeyDownEvent>(OnKeyDown);
    6. }
    7.  
    8. private void OnKeyDown(KeyDownEvent e)
    9. {
    10.     if (e.keyCode == KeyCode.DownArrow || e.keyCode == KeyCode.UpArrow)
    11.         e.StopPropagation(); // might need e.StopImmediatePropagation() if StopPropagation does not fit your needs
    12. }
    Let me know if that doesn't work.
     
  3. Hungweng6

    Hungweng6

    Joined:
    Jan 7, 2014
    Posts:
    9
    Thank you @sebastiend-unity, I've tried that already and it doesn't work unfortunately..
    I can register for key events, but can't stop it from processing the keys
     
  4. sebastiend-unity

    sebastiend-unity

    Unity Technologies

    Joined:
    Nov 9, 2015
    Posts:
    184
    Hmm. Deriving from TextField and overriding ExecuteDefaultActionAtTarget() may do the trick:

    Code (CSharp):
    1. public class MyTextField : TextField
    2. {
    3.     public override void ExecuteDefaultActionAtTarget(EventBase evt)
    4.     {
    5.         if (evt.eventTypeId == KeyDownEvent.TypeId()&&
    6.             (e.keyCode == KeyCode.DownArrow ||
    7.              e.keyCode == KeyCode.UpArrow))
    8.         {
    9.             e.PreventDefault();
    10.             return;
    11.         }
    12.         base.ExecuteDefaultActionAtTarget(evt);
    13.     }
    14. }
     
  5. Hungweng6

    Hungweng6

    Joined:
    Jan 7, 2014
    Posts:
    9
    Thank you again @sebastiend-unity
    I just tried using a custom element derived from TextField and override ExecuteDefaultActionAtTarget() according to your suggestion, but it still doesn't stop it from processing the keys...
     
  6. sebastiend-unity

    sebastiend-unity

    Unity Technologies

    Joined:
    Nov 9, 2015
    Posts:
    184
    Ok, last resort, Go back to the first solution I suggested (OnKeyDown on the TextInput), but add e.PreventDefault() before you exit:

    Code (CSharp):
    1. private void OnKeyDown(KeyDownEvent e)
    2. {
    3.     if (e.keyCode == KeyCode.DownArrow || e.keyCode == KeyCode.UpArrow) {
    4.         e.PreventDefault();
    5.         e.StopImmediatePropagation();
    6. }
    Fingers crossed.
     
    Timboc likes this.
  7. Hungweng6

    Hungweng6

    Joined:
    Jan 7, 2014
    Posts:
    9
    Thank you @sebastiend-unity! that worked, using e.PreventDefault() alone is enough. Thank you again for your help.
     
  8. sebastiend-unity

    sebastiend-unity

    Unity Technologies

    Joined:
    Nov 9, 2015
    Posts:
    184
    Glad to hear it worked -- actually PreventDefault alone works in this specific case (w/ TextField) because all key event handling is done in the TextField's ExecuteDefaultActionAtTarget. Best practice in the future you would probably want to stop propagation as well you never know who is also actively listening to events.
     
    Hungweng6 likes this.