How to show touch keyboard on touch interaction with WPF TextBoxes

Development General WPF

8 years ago

Updated November 2016 - .NET Framework 4.6.2 Windows Presentation Foundation (WPF) apps have a bit harder life in the touch-enabled world. In WinRT apps, the touch keyboard shows up automatically when a text field gets focus so that the user can type without the need of a classic keyboard (no interrupting of her touch workflow). For classic desktop apps the situation differs - TextBoxes don't cause the touch keyboard to appear and the user has to open it manually. That is obviously very cumbersome.

TouchKeyboard

Hey! How can I get you to my WPF app?

There are two different workarounds for this problem.

The hack-y way

The first solution is quite a bit of hacking. This requires us to turn off the inking support for our WPF app and actually force the system to behave the right way. You will need some COM import and call native Windows API. This process is extremely well described here on Brian Lagunas' blog and I encourage you to try it out. If it works for you, great! The disadvantage of this solution, that I discovered, is that it interferes with touch "panning" of ListBox controls. Any try to do touch panning only fires ItemClick events on the hovered items and the user needs to scroll using the small scroll bar and that is more than inconvenient.

The simple, but more manual way

To overcome the issues that come after disabling inking support in your WPF app, we can go with a simpler but less automatic solution. We will extend the TextBox control and change its behavior when it gets touch focus.

public class TouchEnabledTextBox : TextBox
{
    public TouchEnabledTextBox()
    {
        this.GotTouchCapture += TouchEnabledTextBox_GotTouchCapture;
    }

    private void TouchEnabledTextBox_GotTouchCapture(object sender, System.Windows.Input.TouchEventArgs e)
    {
        string touchKeyboardPath = @"C:\Program Files\Common Files\Microsoft Shared\Ink\TabTip.exe";        
        Process.Start( touchKeyboardPath );
    }
}

So how does this work? When the TextBox receives focus after the user enters it with touch, the GotTouchCapture event is called. In this event we can manually start up the process of touch keyboard. The touch keyboard is just a classic desktop application that lives on the path "C:\Program Files\Common Files\Microsoft Shared\Ink\TabTip.exe". This solution is very simple and doesn't require any "hacking" per-se. The only disadvantage is that you as the developer have to ensure, that you use this modified version of TextBox control every time you need to get the right touch-based behavior.

Killing the process

A logical extension to this is to kill the touch keyboard process when it is no longer needed - the input loses focus. The Process.Start( string ) method returns an instance of Process class which provides a Kill() method that will terminate the process when called. First we need to store the process instance in a private field of the TextBox:

//inside the class definition
private Process _touchKeyboardProcess = null;

//replace Process.Start line from the previous listing with
_touchKeyboardProcess = Process.Start( touchKeyboardPath );

Now we wire up the LostFocus event:

//add this at the end of TouchEnabledTextBox's constructor
this.LostFocus += TouchEnabledTextBox_LostFocus;

//add this method as a member method of the class
private void TouchEnabledTextBox_LostFocus( object sender, RoutedEventArgs eventArgs ){
   if ( _touchKeyboardProcess != null ) 
   {
      _touchKeyboardProcess.Kill();
      //nullify the instance pointing to the now-invalid process
      _touchKeyboardProcess = null;
   }
}

Update - Windows 10 way

In Windows 10, this becomes much less of a problem thanks to the new Tablet mode and settings.

Tablet mode

tablet-modeThe newest version of Windows brings a new mode called Tablet mode, which can be turned on via the Action center or in Settings app, and which is optimized for touch first usage. While some see the way it works as a downgrade opposed to Windows 8.1, it presents much more inuitive integration of both new Windows Store apps and classic desktop applications. Each app defaults to full-screen while preserving the multitasking option of two apps side-by-side. Another nice consequence of turning the Tablet mode on is that the touch keyboard is automatically triggered every time any text field gets focus, no matter the type of application. This undoes the need to launch the touch keyboard manually and lets the operating system take the wheel and ensure everything is handled corretly. The only disadvantage as opposed to the modern applications is the fact, that keyboard doesn't shift nor resize the app window and overlays it (even in case it is pinned to the bottom of the screen). This means, that some content may become invisible (for example tooltips or context menus).

Outside of Tablet mode

But what about the case when you, for some reason don't want the Tablet mode on but still want to enjoy the automatic handling of text input by the operating system? A inconspicuous setting can make just this happen! Open the Settings app, go to Devices category and select Typing - here scroll down and you will see a setting that is by default turned off (for some reason, I can't really understand why) - to show the touch keyboard in case of input while no keyboard is attached. This is the perfect solution for most cases and makes using all apps with touch a very pleasant and consistent experience. touch

Updated - .NET Framework 4.6.2

In August 2016 Microsoft announced a new update of .NET Framework 4.6.2. In addition to a very useful addition of Per-Monitor DPI for WPF, this update also addressed the problem with touch keyboard. WPF apps targeting the new version of the framework support automatic invocation and dismissal of the touch keyboard, matching the behavior of UWP apps on Windows 10. That means you don't have to make any additional changes to your new apps to support the touch keyboard. softkeyboard