Onscreen keyboard trouble


So, in one of my recent projects I’ve been working on a Windows 8 store app, the app has several pages with lists containing text and radio buttons in the most cases but in some cases the list contains large text boxes as well. And when you click in one of the text boxes on a Windows 8 tablet without an external keyboard there might occur some problems. I will describe the problem and how it can be solved.

When an element is clicked in a Windows 8 store app that requires input from the user the operative system will display a on screen keyboard. Since this keyboard occupies some space on the screen the OS needs to handle that, this is done by adding a scroll viewer around all content. This usually works fine, but if you have a scrollable list that occupies more or less the whole screen then there will be a scrollviewer around that scrollable list and when you then try to scroll in the list the scrolling will behave very strange and will not provide a good user experience.

This can be solved by changing the height of the scrollable list to the remaining height of the screen after the on screen keyboard has been shown. This can be done with the following code snippet.

// Constructor
public DemoPage()
{
    // Get the input pane from the view and subscribe to the show and hide events 
	var inputPane = InputPane.GetForCurrentView();
	inputPane.Showing += InputPane_Showing;
	inputPane.Hiding += inputPane_Hiding;
}

private void InputPane_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
	// Since the screen will be a lot smaller when the keyboard is showing I suggest that you hide elements
	// that is not needed for the user while entering the text. In my case i am hiding the top pane 
	// where current page text, logo and some other info are located.
	TopPane.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
	TopPane.UpdateLayout();
	
	// Set the scrollable list to occupy the whole grid in height.
	Grid.SetRow(ScrollableListView, 0); 
	Grid.SetRowSpan(ScrollableListView, 4); // I had 4 rows in my main grid.
	
	// Calculate the remaining height of the screen.
	// This can be done by using the bottom y-coordinate of the on screen keyboard and substract the keyboards height.
	var newHeight = args.OccludedRect.Bottom - args.OccludedRect.Height;
	
	// Set the new height and update the layout.
	ScrollableListView.Height = newHeight;
	ScrollableListView.UpdateLayout();
	
}

private void inputPane_Hiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
	// Show the top pane again
	TopPane.Visibility = Visibility.Visible;
	TopPane.UpdateLayout();
	
	// Reset the grid row and rowspan of the scrollable list.
	Grid.SetRow(ScrollableListView, 2);
	Grid.SetRowSpan(ScrollableListView, 1);
	
	// Reset the height of the scrollable list and update the layout.
	ScrollableListView.Height = double.NaN;
	ScrollableListView.UpdateLayout();
}