Keyboard navigation in WPF TreeView

2019-05-12 04:35发布

问题:

My TreeViewItem.Items data template contains 2 textboxes. When I press Tab key in first textbox, focus goes on second textbox. I want to when I press Tab on second textbox - focus going on first textbox on next TreeViewItem subitem and if there are TreeViewItem has not next subitem, focus goes on first subitem on next TreeViewItem. How to do that?

<TreeView Name="resultsTv" 
            ItemTemplate="{StaticResource excerciseResultDataTemplate}" 
            KeyboardNavigation.TabNavigation="Contained">
                <TreeView.ItemContainerStyle>
                    <Style>
                        <Setter Property="TreeViewItem.IsExpanded" Value="True"/>
                        <Setter Property="KeyboardNavigation.TabNavigation" Value="Contained"></Setter>
                    </Style>
                </TreeView.ItemContainerStyle>
            </TreeView>

<HierarchicalDataTemplate x:Key="excerciseResultDataTemplate" ItemTemplate="{StaticResource setDataTemplate}" ItemsSource="{Binding Sets}">
            <StackPanel Orientation="Horizontal" KeyboardNavigation.TabNavigation="Continue">
                <Label Content="{Binding Name}"></Label>
            </StackPanel>
        </HierarchicalDataTemplate>

<DataTemplate x:Key="setDataTemplate">
            <StackPanel Orientation="Horizontal" KeyboardNavigation.TabNavigation="Continue">
                <TextBox Width="50" Text="{Binding Weight}"/>
                <TextBox Width="50" Text="{Binding Repeats"/>
            </StackPanel>
        </DataTemplate>

回答1:

Having this problem myself I looked this up on the internet and only saw forum posts about commercial custom controls for WPF. However, since they rely on the generic container design of WPF they still work:

Set the KeyboardNavigation.TabNavigation property of your TreeView tag to Contained and include the following in your tree:

<TreeView.ItemContainerStyle>
    <Style TargetType="TreeViewItem">
        <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/>
    </Style>
</TreeView.ItemContainerStyle>

There are three problems with this. Shift-tab simply doesn't work. (See this question.) Additionally, the up and down arrow keys don't do much. And I just discovered doing this will handle the MouseLeftButtonUp event so that your own event won't be triggered.