How to show touch keyboard on touch interaction with WPF TextBoxes

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.

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:

Now we wire up the LostFocus event:

 

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

18 Replies to “How to show touch keyboard on touch interaction with WPF TextBoxes”

    1. The user can dismiss the keyboard manually by clicking its close button. For a more intuitive approach you can kill the started process of the keyboard when the TextBox loses focus. I will update the article with an example 🙂

  1. The Manual way works fine !Thank you for this trick 🙂
    But if I want to edit another textBox I need to double-touch the new TextBox in order to get the focus. Do you know a simple way to use simple tap instead of double tap ?

  2. This statement is not correct!

    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.

    I have tested with a VB6 32 Bit app and the only control I found so far that will shpow the keyboard is a ComboDropDown and if you set to DropList will not show the keyboard?

    Thoughts?

    I am running the Surface Pro 4 in tablet mode on the latest version of Windows 10

    1. I didn’t have a chance to test out any VB6 app, so you are probably correct. I have tested only WPF and WinForms apps. A will update the article appropriately

  3. On a side note for VB6:

    This works well but you would need to add a code call for every control in your app

    Public Declare Function ShellExecute Lib “shell32.dll” Alias “ShellExecuteA” _
    (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long

    Public Sub ShowKeyboard()

    On Error Resume Next

    ShellExecute 0&, vbNullString, “C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe”, vbNullString, vbNullString, 1

    End Sub

    Private Sub txt1_GotFocus(Index As Integer)

    ShowKeyboard

    End Sub

  4. I’m most interested in the last update for 4.6.2. My WPF application is targeting 4.6.2 and I’m not seeing this behavior. Any suggestions on what I might be missing?

    1. Maybe I should qualify this some. The keyboard is coming up automatically when in Tablet Mode. I think I was getting this behavior on 4.5.2 as well.

      My app does not move or resize itself with the keyboard, which is really what I need.

    2. You need to have Anniversary Update installed. Otherwise you might also want to check the Settings app as mentioned in the article if the setting to show touch keyboard outside of Tablet mode is enabled.

  5. Hi Martin thanks for such a useful post. I’m dealing with a WPF app which runs as a custom shell on Windows 10 Pro 1607, however as limited resources are available when using a custom shell, there is no way to call the keyboard when touching text boxes. Any idea how can this be achieved, thanks, Jorge.

  6. Thanks martin, targeting .net 4.6 should solve it, however regarding to the manual solution, do I create a class that extends or overrides the textcontrol class?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*