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导航焦点问题

为啥 Gdk::Pixbufs 在 Gtk::TreeView 中不可见?

VB treeview 中各控件的属性

c# 后台绑定treeview 单个tab

TreeView控件