Windows 8 - How to Dismiss Touch Keyboard?

thisnick picture thisnick · Aug 27, 2012 · Viewed 7.9k times · Source

I am developing my app for Windows 8 in C#, and one very annoying thing is that the touch keyboard sometimes stays on screen even though all textboxes have lost focus.

I read the article keyboard dismissal logic white paper, which explains that when switching from control to control, the keyboard can stay on even though a control may not accept keyboard input. This would be my case because all my contents are hosted in either a GridView or a ListView. When the user clicks on any item on screen, the tap would land on these controls. This is very annoying because the keyboard takes half of a screen and there is no way to close the keyboard.

I have tried to set the textbox to be disabled and it had not affect. The only way to remove the keyboard is to set focus on a button, which is extremely hacky.

I thought I needed to do something with the "AutomationPeer", but I am not clear what exactly to do. Is there a way to override this behavior?

Edit: I figured this out. The goal is to change to the control type of the GridView and GridView item not listed in the whitepaper. Here is the code of the grid that I did that allowed me to dismiss the keyboard:

public class KeyboardUnfocusableGridView : GridView
{
    private class KeyboardUnfocusableGridViewAutomationPeer : GridViewAutomationPeer
    {
        public KeyboardUnfocusableGridViewAutomationPeer(GridView owner)
            : base(owner)
        {
        }

        protected override AutomationControlType GetAutomationControlTypeCore()
        {
            return AutomationControlType.Custom;
        }

    }

    private class KeyboardUnfocusableGridViewItemAutomationPeer : GridViewItemAutomationPeer
    {
        public KeyboardUnfocusableGridViewItemAutomationPeer(GridViewItem owner)
            : base(owner)
        { }

        protected override AutomationControlType GetAutomationControlTypeCore()
        {
            return AutomationControlType.Custom;
        }

    }

    private class KeyboardUnfocusableGridViewItem : GridViewItem
    {
        protected override AutomationPeer OnCreateAutomationPeer()
        {
            var baseItem = base.OnCreateAutomationPeer();
            return new KeyboardUnfocusableGridViewItemAutomationPeer(this);
        }


    }

    protected override AutomationPeer OnCreateAutomationPeer()
    {
        var baseItem = base.OnCreateAutomationPeer();
        return new KeyboardUnfocusableGridViewAutomationPeer(this);
    }

    protected override Windows.UI.Xaml.DependencyObject GetContainerForItemOverride()
    {
        return new KeyboardUnfocusableGridViewItem();
    }
}

It's unfortunate that I need to write this much code to do a simple thing. This is definitely not optimal since I would need to do this for each of the ItemsControl that I need to use.

Answer

Jared Bienz - MSFT picture Jared Bienz - MSFT · Aug 27, 2012

What you need to do is set focus to any control that does not accept text entry. However, be aware that if the user manually showed the keyboard (as opposed to it automatically showing because a TextBox received focus) then the keyboard will remain open.

Check out this really good thread about the on-screen keyboard for more info:

http://social.msdn.microsoft.com/Forums/pl/winappswithcsharp/thread/3c227262-1d2c-4382-9c50-5b71d2b5d823