Reputation: 12906
My Windows 8 XAML page contains two controls: Image and TextBox. When the user doubletaps Image, I want to move the focus to TextBox so that the virtual keyboard is automatically displayed.
The problem: The TextBox control correctly receives the focus, but only for 0.1 seconds. The focus then moves to somewhere else and no keyboard is displayed.
Through the events I can see that GotFocus and and LostFocus events are raised for the TextBox. The Image control doesn't have other event handlers as it only handles the DoubleTapped event:
private void CurrentPage_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
e.Handled = true;
this.PageNumberTextBox.Focus(FocusState.Keyboard);
}
Why doesn't the focus "stick"? Where and why the focus goes?
Update:
With this very helpful helper I can see that the focus moves to ScrollViewer [Windows.UI.Xaml.Controls.Border]. I presume this is something which is built-in (maybe used by the RootFrame?) as I don't have any ScrollViewers added to the page and because this control seems to fill the whole screen.
So, the problem seems to be caused by event bubbling: Image-control is first to receive the event and then the control behind it. But why? Shouldn't e.Handled = true prevent this behavior?
Modifying the code to look like this doesn't help:
private void CurrentPage_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
e.Handled = true;
//this.PageNumberTextBox.Focus(FocusState.Keyboard);
}
After the doubletap, the mystery ScrollViewer has the focus.
Update 2:
The problem might be related to Image-control. I created the following spike:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Grid.Row="0" DoubleTapped="UIElement_OnDoubleTapped" Tapped="UIElement_OnTapped"
Source="http://upload.wikimedia.org/wikipedia/commons/1/1c/Squirrel_posing.jpg" Stretch="Fill"/>
<TextBox x:Name="MyBox" Grid.Row="1"/>
</Grid>
The spike app is created using the Blank template. In code behind I set the e.Handled = true for both Tapped and DoubleTapped:
private void UIElement_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
e.Handled = true;
}
private void UIElement_OnTapped(object sender, TappedRoutedEventArgs e)
{
e.Handled = true;
}
The problem: When I tap the Image, the focus is always given to this mystery ScrollViewer. Here's some screenshots:
So even though I've set the Image to handle both Tapped and DoubleTapped, the Image control doesn't receive the focus.
Upvotes: 4
Views: 2848
Reputation: 35881
I think your problem is the double-tap is within a series of events that end up changing the focus. What you could try is to "queue" a focus change by asynchronously calling the Focus method. For example:
Task.Factory.StartNew(
() => Dispatcher.RunAsync(CoreDispatcherPriority.Low,
() => PageNumberTextBox.Focus(FocusState.Keyboard)));
I know it looks a little stupid but what this does is to try to put the code that changes the focus after all the other events in the queue.
Upvotes: 3