UWP用户控件双击后焦点转移至RootScrollViewer问题排查
UWP用户控件双击焦点异常问题解决
问题现象
我有一个简单的UWP用户控件,设置了双击和单击事件,希望双击时执行操作并保留焦点。实际表现为:
- 单击控件时,焦点能正常停留在控件上
- 双击控件内的TextBlock时,焦点先移至控件,但随后立即切换到可视化树中的RootScrollViewer,手动在DoubleTapped事件里调用
this.Focus(FocusState.Programmatic)也无法留住焦点
控件XAML代码:
... DoubleTapped="UserControl_DoubleTapped" Tapped="UserControl_Tapped" IsDoubleTapEnabled="True" IsTapEnabled="True" AllowFocusOnInteraction="True" TabIndex="0" IsTabStop="True" > <Grid Background="Gray" BorderBrush="Green" BorderThickness="3" CornerRadius="10"> <TextBlock Text="Hello World" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid>
后台代码:
private void UserControl_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { // 执行操作 // 尝试重新设置焦点但无效 this.Focus(FocusState.Programmatic); } private void UserControl_Tapped(object sender, TappedRoutedEventArgs e) { this.Focus(FocusState.Programmatic); }
演示效果:双击时焦点短暂停留在控件,随后跳转到RootScrollViewer;单击时焦点稳定保留在控件上。
问题原因
UWP中TextBlock默认支持文本选择功能,双击TextBlock会触发系统内置的文本选择逻辑,这个逻辑会将焦点转移到负责文本区域滚动/选择管理的父级ScrollViewer。而DoubleTapped事件触发后,系统后续的文本选择处理会覆盖手动设置的焦点操作,导致焦点被抢走。
解决方案
方案1:禁用TextBlock的文本选择功能
在XAML的TextBlock中添加IsTextSelectionEnabled="False"属性,彻底阻止双击触发文本选择行为:
<TextBlock Text="Hello World" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" IsTextSelectionEnabled="False"/>
方案2:标记DoubleTapped事件已处理
在后台的DoubleTapped事件方法中添加e.Handled = true;,阻止事件继续传递到系统的文本选择处理逻辑:
private void UserControl_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { // 执行操作 e.Handled = true; // 阻止后续默认行为 this.Focus(FocusState.Programmatic); }
这两种方法都可以避免双击时焦点被RootScrollViewer抢走,让焦点稳定保留在用户控件上。
内容的提问来源于stack exchange,提问作者FrozenAssassine
相关产品推荐
相关产品推荐

