Friday, August 10, 2012

Windows 8: Hide Virtual Keyboard Programmatically

The visibility of the virtual keyboard in Windows 8 Metro Style Apps depends on whether a text input enabled control is focused or not:

In the left image the user tapped into a TextBox control. This tap sets the focus on that TextBox and the virtual keyboard appeared. After having entered some Text the user taps the “OK” button and the virtual keyboard hides again due to the loss of focus (right image).

with keyboard       without keyboard copy

But sometimes there is no Button control to hit after having entered some text and thus the virtual keyboard does not hide and still might cover important parts of the UI. In order to hide the virtual keyboard no matter where the user taps outside the TextBox one could set the focus to a hidden button programmatically.

See the following example:

XAML Markup:

   1: <Grid>
   2:   <Button x:Name="hiddenButton" Opacity="0" />
   3:   <TextBox Width="300" Margin="50" 
   4:            LostFocus="TextBox_LostFocus" />
   5: </Grid>

C# Code Behind:



   1: private void TextBox_LostFocus(object sender, RoutedEventArgs e)
   2: {
   3:     this.hiddenButton.Focus(Windows.UI.Xaml.FocusState.Pointer);
   4: }

1 comment:

  1. There is another solution.

    You can create an TouchKeyboardHelper.cs class and declare system message to find the soft keyboard and force to close it.

    The TouchKeyboardHelper.cs must be like:

    using System.Runtime.InteropServices;
    using Windows.Devices.Input;

    namespace Application_Photo_GRDF.Common
    {
    public static class TouchKeyboardHelper
    {
    #region < Attributes >

    private const int WM_SYSCOMMAND = 0x0112; // Flag to received/send messages to the system.
    private const int SC_CLOSE = 0xF060; // Param to indicate we want to close a system window.

    #endregion < Attributes >

    #region < Properties >

    public static bool KeyboardAttached
    {
    get { return IsKeyboardAttached(); }
    }

    #endregion < Properties >

    #region < Methods >

    [DllImport("user32.dll")]
    private static extern int FindWindow(string lpClassName, string lpWindowName); // To obtain an active system window handler.

    [DllImport("user32.dll")]
    private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); // To send a message to the system.

    ///
    /// To detect if a real keyboard is attached to the dispositive.
    ///
    ///
    private static bool IsKeyboardAttached()
    {
    KeyboardCapabilities keyboardCapabilities = new KeyboardCapabilities(); // To obtain the properties for the real keyboard attached.
    return keyboardCapabilities.KeyboardPresent != 0 ? true : false;
    }

    ///
    /// To close the soft keyboard
    ///
    public static void CloseOnscreenKeyboard()
    {
    // Retrieve the handler of the window
    int iHandle = FindWindow("IPTIP_Main_Window", ""); // To find the soft keyboard window.
    if (iHandle > 0)
    {
    SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0); // Send a close message to the soft keyboard window.
    }
    }

    #endregion < Methods >
    }
    }

    An to use that helper in our code add something like......

    if (TouchKeyboardHelper.KeyboardAttached)
    {
    TouchKeyboardHelper.CloseOnscreenKeyboard();
    }

    ReplyDelete