One of the “interesting” things about Silverlight apps running on Windows is that on touch/tablet systems, textboxes in Silverlight do not display a popup button to use for bringing up the Windows onscreen keyboard when they have focus, whereas native applications do.
WPF / Native Window following a “Touch” in a textbox
Silverlight OOB Window following a “Touch” in a textbox
The onscreen keyboard is actually present in the Silverlight case – it is usually just “conveniently” tucked against the left side of the screen – and experience has shown me that until you actually show or describe to someone where it is, they will usually not find it on their own. Tap it once, and it “peeks” out a little bit. Tap it again, and it is brought to the center of the screen. Hit the close button, and it returns to its tucked away position on the side of the screen.
I have been asked several times for an option to show the onscreen keyboard from within a Silverlight application in a more consistent and user-friendly fashion. It turns out that for Silverlight Out of Browser applications running with Elevated Trust, there is an option – COM Automation can be used to invoke the process that displays the onscreen keyboard, or Text Input Panel (TIP).
Locating the Process
As of Windows Vista, the TextInputPanel handles the Tablet Input Panel (TIP). This is implemented in the file TabTip.exe, which exists in the directory <Program Files>\Common Files\Microsoft Shared\ink – this is true both in 64-bit and 32-bit versions of Windows. (Note – I have verified this myself only on Windows 7.) See the following site for more information about the TIP: http://msdn.microsoft.com/en-us/library/ms701746(VS.85).aspx.
Normally, to locate the needed path, the Environment.GetFolderPath method would be used. However, when called on a 64-bit system from Silverlight with SpecialFolder.CommonProgramFiles as the parameter, it returns the path to the x86 Program Files directory…not the one that is needed in this case. However, using the scripting shell’s ExpandEnvironmentStrings method can get the correct value, as follows:
1: dynamic shell = AutomationFactory.CreateObject("WScript.Shell");
2: String commonPath = shell.ExpandEnvironmentStrings("%CommonProgramW6432%");
4: // This path is the same for both 32 and 64-bit installs of Windows
5: String filePath = System.IO.Path.Combine(commonPath, @"microsoft shared\ink\TabTip.exe");
Information about the CommonProgramW6432 Environment Variable can be found at this link: http://msdn.microsoft.com/en-us/library/aa384274(VS.85).aspx.
Showing the Onscreen Keyboard
Now that the necessary program has been located, it simply needs to be run to show the keyboard (or to bring it up onscreen, in case the keyboard app is running, but “hidden” along the margin, as pictured above. To do this, simply call ShellExecute, passing in the path calculated above:
1: dynamic application = AutomationFactory.CreateObject("Shell.Application");
2: application.ShellExecute(filePath, "", "", "open", 1);
The full code listing for a ShowKeyboard helper method is shown below:
1: public static class KeyboardHelper
3: public static void ShowKeyboard()
5: if (AutomationFactory.IsAvailable)
9: // Ensure Windows 7 or Windows Server 2008 R2
10: // OS Version # - http://msdn.microsoft.com/en-us/library/ms724832(VS.85).aspx
11: if (Environment.OSVersion.Platform == PlatformID.Win32NT
12: && Environment.OSVersion.Version >= new Version(6, 1))
14: // Get the path to the Common Program Files directory (not the x86 version...)
16: // Environment.GetFolderPath returns the wrong path (x86 branch on 64-bit systems.)
17: // String commonPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles);
19: dynamic shell = AutomationFactory.CreateObject("WScript.Shell");
20: String commonPath = shell.ExpandEnvironmentStrings("%CommonProgramW6432%");
22: // This path is the same for both 32 and 64-bit installs of Windows
23: String filePath = System.IO.Path.Combine(commonPath, @"microsoft shared\ink\TabTip.exe");
25: // Bring up the TIP - http://msdn.microsoft.com/en-us/library/ms701746(VS.85).aspx
26: dynamic application = AutomationFactory.CreateObject("Shell.Application");
27: application.ShellExecute(filePath, "", "", "open", 1);
30: catch (Exception ex)
I have shown how to programmatically show the TIP…as far as how to get there, that is left as an exercise for the reader. In some cases, adding a launcher (such as a “show keyboard” button) somewhere in the UI may be an acceptable option – it is certainly the simplest. To approximate the behavior seen in native applications, more work is required. This includes showing a UI control to display the TIP, which is only displayed if the user accesses the textbox control via touch input. This can be determined by using the Silverlight Multitouch Input APIs, or a helper library such as LightTouch or the Native Extensions for Silverlight.
Thank you for your article. Works perfect. But can you also explain how to hide the keyboard again? Want to use a hiding function after i lost the focus on a specific UI Element.
Thanks a lot in advance.
Greetings from Germany