Update – 4/10/2014  Wow!  Quite a lot has happened since I originally posted this.  Certainly one of the biggest changes is the diminished role that Silverlight now plays in both enterprise and consumer applications.  However, I’ve noticed that this particular blog post is still getting some attention, so I figured I’d try to provide some direction that Silverlight developers might be looking for or otherwise be interested in.

    • First and foremost, if you’re looking for resources to help you evaluate or actually execute a move from Silverlight to an alternate technology, check out the Wintellect Silverlight Migration Strategies page which includes Noel Stieglitz’s whitepaper that discusses various options and strategies that are available to you.  I’d also suggest checking out Microsoft’s free e-book “.NET Technology Guide for Business Applications.” 
    • If you’re interested in concepts related to touch for the new Windows Store Apps, check out the book that I co-authored with Jeremy Likness “Programming the Windows Runtime by Example”.  In particular, Chapter 13 (Devices) deals with concepts related to touch interaction.

 

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.

image
WPF / Native Window following a “Touch” in a textbox

image
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 FilesMicrosoft Sharedink – 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%");
   3:  
   4: // This path is the same for both 32 and 64-bit installs of Windows
   5: String filePath = System.IO.Path.Combine(commonPath, @"microsoft sharedinkTabTip.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
   2: {
   3:     public static void ShowKeyboard()
   4:     {
   5:         if (AutomationFactory.IsAvailable)
   6:         {
   7:             try
   8:             {
   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))
  13:                 {
  14:                     // Get the path to the Common Program Files directory (not the x86 version...)
  15:  
  16:                     // Environment.GetFolderPath returns the wrong path (x86 branch on 64-bit systems.)
  17:                     // String commonPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles);
  18:  
  19:                     dynamic shell = AutomationFactory.CreateObject("WScript.Shell");
  20:                     String commonPath = shell.ExpandEnvironmentStrings("%CommonProgramW6432%");
  21:  
  22:                     // This path is the same for both 32 and 64-bit installs of Windows
  23:                     String filePath = System.IO.Path.Combine(commonPath, @"microsoft sharedinkTabTip.exe");
  24:  
  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);
  28:                 }
  29:             }
  30:             catch (Exception ex)
  31:             {
  32:                 Debug.WriteLine(ex);
  33:             }
  34:         }
  35:     }
  36: }

What’s Next?

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

Update – 4/10/2014

Wow!  Quite a lot has happened since I originally posted this.  Certainly one of the biggest changes is the diminished role that Silverlight now plays in both enterprise and consumer applications.  However, I’ve noticed that this particular blog post is still getting some attention, so I figured I’d try to provide some direction that Silverlight developers might be looking for or otherwise be interested in.

First and foremost, if you’re looking for resources to help you evaluate or actually execute a move from Silverlight to an alternate technology, check out the Wintellect Silverlight Migration Strategies page which includes Noel Stieglitz’s whitepaper that discusses various options and strategies that are available to you.  I’d also suggest checking out Microsoft’s free e-book “.NET Technology Guide for Business Applications.” 

If you’re interested in concepts related to touch for the new Windows Store Apps, check out the book that I co-authored with Jeremy Likness “Programming the Windows Runtime by Example”.  In particular, Chapter 13 (Devices) deals with concepts related to touch interaction.