WinRT XAML并以编程方式将焦点设置为TextBox - 为什么Focus不粘?

时间:2013-12-20 11:01:47

标签: c# winrt-xaml

我的Windows 8 XAML页面包含两个控件:Image和TextBox。当用户双击Image时,我想将焦点移动到TextBox,以便自动显示虚拟键盘。

问题:TextBox控件正确接收焦点,但仅持续0.1秒。然后焦点移动到其他地方,不显示键盘。

通过这些事件,我可以看到为TextBox引发了GotFocus和LostFocus事件。 Image控件没有其他事件处理程序,因为它只处理DoubleTapped事件:

    private void CurrentPage_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        e.Handled = true;
        this.PageNumberTextBox.Focus(FocusState.Keyboard);
    }

为什么焦点不“坚持”?重点放在何处以及为何?

更新

使用this very helpful helper我可以看到焦点移动到 ScrollViewer [Windows.UI.Xaml.Controls.Border] 。我认为这是内置的(可能由RootFrame使用?)因为我没有添加任何ScrollViewers到页面,因为这个控件似乎填满了整个屏幕。

因此,问题似乎是由事件冒泡引起的:图像控制首先接收事件,然后是它背后的控件。但为什么?不应该 e.Handled = true 阻止这种行为吗?

修改代码看起来没那么有用:

    private void CurrentPage_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        e.Handled = true;
        //this.PageNumberTextBox.Focus(FocusState.Keyboard);
    }

在双击后,神秘的ScrollViewer成为焦点。

更新2:

问题可能与图像控制有关。我创建了以下峰值:

<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>

使用空白模板创建加标应用。在后面的代码中,我为Tapped和DoubleTapped设置了e.Handled = true:

    private void UIElement_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        e.Handled = true;
    }

    private void UIElement_OnTapped(object sender, TappedRoutedEventArgs e)
    {
        e.Handled = true;
    }

问题:当我点击图像时,焦点总是给予这个神秘的ScrollViewer。这是一些截图:

  1. 当我单击带有视图下半部分的TextBox时,焦点会正确移动到TextBox(带焦点的控件会突出显示,控件的名称会显示在左上角):
  2. Focus textbox

    1. 单击顶部的图像时,图像无法获得焦点。相反,它被赋予神秘的ScrollViewer,它似乎填满整个屏幕:
    2. Focus image

      因此即使我将Image设置为同时处理Tapped和DoubleTapped,Image控件也不会获得焦点。

1 个答案:

答案 0 :(得分:3)

我认为你的问题是双击是在一系列最终改变焦点的事件中。您可以尝试通过异步调用Focus方法来“排列”焦点更改。例如:

Task.Factory.StartNew(
    () => Dispatcher.RunAsync(CoreDispatcherPriority.Low,
        () => PageNumberTextBox.Focus(FocusState.Keyboard)));

我知道它看起来有点愚蠢,但它的作用是尝试在队列中的所有其他事件之后放置改变焦点的代码。