Shift + Tab在TreeView控件中不起作用

时间:2010-05-27 08:38:55

标签: c# wpf treeview navigation

我无法使用Shift + Tab在包含TextBox的TreeView中工作,使用Tab正向导航工作正常并从TreeBox中的TextBox跳转到TextBox。无论何时使用Shift + Tab,当TreeView中的一个TextBox,然后焦点移动到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>

2 个答案:

答案 0 :(得分:7)

如果您使用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);
    }
}

答案 1 :(得分:0)

您不必使用从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。