Shift+Tab 在 TreeView 控件中不起作用
Posted
技术标签:
【中文标题】Shift+Tab 在 TreeView 控件中不起作用【英文标题】:Shift+Tab not working in TreeView control 【发布时间】:2011-02-24 13:32:43 【问题描述】:我无法使用 Shift+Tab 向后导航以在包含 TextBox 的 TreeView 中工作,使用 Tab 向前导航可以正常工作并在 TreeView 内从 TextBox 跳转到 TextBox。任何时候当 TreeView 内的 TextBox 之一使用 Shift+Tab 时,焦点就会移到 TreeView 外的上一个控件,而不是 TreeView 内的上一个控件。
此外,它唯一不能正常工作的 Shift+Tab 导航,Ctrl+Shift+Tab 按预期工作并按正确顺序工作。
对我做错了什么有什么建议吗?
示例代码:
<Window x:Class="TestTabTreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="KeyboardNavigation.TabNavigation" Value="Continue" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Text="First Line" Grid.Row="0" />
<TreeView Grid.Row="1" KeyboardNavigation.TabNavigation="Continue" IsTabStop="False">
<TreeViewItem IsExpanded="True"><TreeViewItem.Header><TextBox Text="Popular Words"/></TreeViewItem.Header>
<TreeViewItem><TreeViewItem.Header><TextBox Text="Foo"/></TreeViewItem.Header></TreeViewItem>
<TreeViewItem><TreeViewItem.Header><TextBox Text="Bar"/></TreeViewItem.Header></TreeViewItem>
<TreeViewItem><TreeViewItem.Header><TextBox Text="Hello"/></TreeViewItem.Header></TreeViewItem>
</TreeViewItem>
<TreeViewItem IsExpanded="True"><TreeViewItem.Header><TextBox Text="Unpopular Words"/></TreeViewItem.Header>
<TreeViewItem><TreeViewItem.Header><TextBox Text="Work"/></TreeViewItem.Header></TreeViewItem>
<TreeViewItem><TreeViewItem.Header><TextBox Text="Duplication"/></TreeViewItem.Header></TreeViewItem>
</TreeViewItem>
</TreeView>
<TextBox Text="Last Line" Grid.Row="2" />
</Grid>
【问题讨论】:
【参考方案1】:如果您使用 ILSpy/Reflector 查看 TreeView.OnKeyDown 处理程序,您可以看到问题的原因。当按下 Shift+Tab 时,TreeView 有特殊处理。相关代码为:
Key key = e.Key;
if (key != Key.Tab)
// ...
else
if (TreeView.IsShiftKeyDown && base.IsKeyboardFocusWithin &&
this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous)))
e.Handled = true;
return;
不幸的是,您需要使用自定义 TreeView 类来解决此问题。这样的工作:
public class MyTreeView : TreeView
protected override void OnKeyDown(KeyEventArgs e)
if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0 && e.Key == Key.Tab)
return;
base.OnKeyDown(e);
【讨论】:
【参考方案2】:您不必使用继承自 TreeView 的自定义类:
treeView.PreviewKeyDown += this.HandleTreeView_PreviewKeyDown
与:
private void HandleTreeView_PreviewKeyDown(object sender, KeyEventArgs e)
if (e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Shift)
&& e.Key == Key.Tab)
var focusedElement = Keyboard.FocusedElement;
if (focusedElement != null)
focusedElement.MoveFocus(FocusNavigationDirection.Previous, 1);
e.Handled = true;
也可以正常工作。
例如,使用此解决方案,您可以创建自定义行为并将其附加到您的 TreeView。
【讨论】:
以上是关于Shift+Tab 在 TreeView 控件中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
treeview.expandall 方法在 backgroundworker 完成事件 WPF 中不起作用
WPF 键盘导航附加属性解决TreeView的Tab导航焦点问题