Windows Phone 8.1 WinRT App TextBox GotFocus 事件意外触发

有开发者发现在Windows Phone 8.1 WinRT app中,使用TextBox控件在某种特殊布局情形下,其GotFocus事件会被意外触发。如下XAML内容,该页面包含一个TextBox 控件和一个Button 按钮,运行程序,点击Button 按钮时会触发该页面上TextBox的GotFocus事件。

    <Grid>      

           <TextBox x:Name="tb" Foreground="Gray" Text="评论..." GotFocus="tb_GotFocus" />       

           <Button x:Name="btn" Content="Button" Click="btn_Click" Margin="163,394,0,189" />

    </Grid>

       private void btn_Click(object sender, RoutedEventArgs e)

        {

              btn.IsEnabled = false;

        }

         //TextBox框获焦点

        private async void tb_GotFocus(object sender, RoutedEventArgs e)

        {

                 MessageDialog msgDialog = new MessageDialog("TextBox GotFocus 获得焦点", "Reminder");

                 msgDialog.Commands.Add(new UICommand("Yes", (cmd) =>

                 {

                       Frame.Navigate(typeof(PageYes));

                 }));

                msgDialog.Commands.Add(new UICommand("Cancel"));

                await msgDialog.ShowAsync();        

        }

 

为何会发生该行为呢?原因在于为了与传统的桌面应用保持相对一致性如Tab键的操作,WinRT的app做了对应的改进,当页面上的控件获得焦点(点击Button 按钮)再失去焦点时(设置Button的IsEnabled属性为false,使之不能再进行用户交互),OS会使得逻辑树上的第一个控件得到焦点, 若设置了控件的TabIndex值,则会将焦点落在Active的TabIndex值最小的控件。在如上demo 里,由于只有2个控件,所以当disable Button的用户交互能力后,焦点会自动落到剩余的控件-即TextBox上。若希望规避该现象,可以添加另外一个控件代替TextBox 接收焦点。如下添加一个Button控件并将其拖动到屏幕之外以隐藏该控件,或者也可以根据需求进行相应更好的布局。

 

      <Grid>

            <Button Width="40" Height="40" Margin="63,659,0,-76" />

            <TextBox x:Name="tb" Foreground="Gray" Text="评论..." GotFocus="tb_GotFocus" />       

            <Button x:Name="btn" Content="Button" Click="btn_Click" Margin="163,394,0,189" />

    </Grid>