3
votes

Strange behavior (to me) when I have a TextBox in a UWP app.

  • Create a Universal, Blank App UWP app in Windows 10.
  • Add a TextBox to the default grid with this code:
    <TextBox Text="There's not much spam in it" Name="textBox" />
  • Build and run the application.
  • Click inside of the TextBox
  • Type Control-I.

A tab is inserted.

What causes this behavior?

I'm trying to set up window level shortcuts in a Windows 10 application by hooking up a handler to Window.Current.CoreWindow.KeyDown, but I think that's too late in the event game to catch the Control-I's tab insertion and call it handled. That, I think the TextBox's KeyDown is completely handled before the CoreWindow's event occurs.

So for now I'm settling for handling the event on each TextBox whenever someone selects Control-I like this...

Edit XAML to this:

<TextBox Text="There's not much spam in it" 
    Name="textBox" KeyDown="textBox_KeyDown" AcceptsReturn="True" />

Add event handler:

private void textBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
    if (e.OriginalKey.Equals(VirtualKey.I) 
        && Window.Current.CoreWindow.GetKeyState(VirtualKey.Control)
        .HasFlag(CoreVirtualKeyStates.Down))
    {
        this.textBox.SelectedText += "X";
        e.Handled = true;
    }
}

... which seems to work okay, except that now I have to slap my "window" scope event handler for Control-I into each TextBox (or extend TextBox, both of which seem crazy for what seems to be a non-standard keyboard shortcut).

So primarily I'm asking what action it is that inserts a Tab into a TextBox when Control-I is pressed, and if there's a better way to avoid that action at the CoreWindow level. A better means of capturing keyboard shortcuts at the CoreWindow level (eg, Ctrl-K means insert a link) would also be appreciated, but wouldn't really answer the "real" question.

1
Hrm. I think I'm wrong. I think I can just rig up a TextBox with a special KeyDown handler that says the event is handled (from the pov of the TextBox) and be done with it. Not sure why that didn't seem to be working before. Still wondering where Ctrl-I == insert a tab, but maybe not such a big deal. - ruffin

1 Answers

2
votes

The best solution I've found to date is to insert an event handler for KeyDown that will eat Ctrl-I.

I have a fuller solution on GitHub that addresses this and some other issues here, but here's the operative Ctrl-I eating code:

public UWPBox() : base()
{
    this.KeyDown += this.KeyDownHandler;
}

public virtual async void KeyDownHandler(object sender, KeyRoutedEventArgs e)
{
    bool isCtrlDown = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control)
        .HasFlag(CoreVirtualKeyStates.Down);

    try
    {
        switch (e.OriginalKey)
        {
            case VirtualKey.I:
                // First, kill the default "Ctrl-I inserts a tab" action.
                if (isCtrlDown)
                {
                    e.Handled = true;
                    this.HandleCtrlI(); // Just in case we want to do 
                                        // something different with Ctrl-I
                }
                break;

            // "Fixes" for Ctrl-V and Tab removed.
            // Fuller solution here: https://github.com/ruffin--/UWPBox
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(
            DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ": " 
            + ex.Message);
    }
}

public virtual void HandleCtrlI()
{
    System.Diagnostics.Debug.WriteLine("Ctrl-I pressed.");
}