Shift+Tab not working in TreeView control
I cannot get backwards navigation using Shift+Tab to work in a TreeView that contains TextBoxs, forward navigation using Tab works fine and jump from TextBox to TextBox inside the TreeView. Anytime Shift+Tab is used when one of the TextBoxes inside the TreeView, then the focus is move to the previous control outside the TreeView, instead of the previous control inside the TreeView.
Also its only Shift+Tab navigation that are not working correctly, Ctrl+Shift+Tab work as expected and in the correct order.
Any suggestions to what I'm doing wrong?
Example code:
<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.RowDefinitio开发者_运维问答ns>
<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>
If you look in the TreeView.OnKeyDown handler using ILSpy/Reflector, you can see the cause of your issues. The TreeView has special handling when Shift+Tab is pressed. The relevant code is:
Key key = e.Key;
if (key != Key.Tab) {
// ...
}
else {
if (TreeView.IsShiftKeyDown && base.IsKeyboardFocusWithin &&
this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous))) {
e.Handled = true;
return;
}
}
Unfortunately, you'd need to use a custom TreeView class to work around this. Something like this works:
public class MyTreeView : TreeView {
protected override void OnKeyDown(KeyEventArgs e) {
if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0 && e.Key == Key.Tab)
return;
base.OnKeyDown(e);
}
}
You don't have to use a custom class inherited from TreeView:
treeView.PreviewKeyDown += this.HandleTreeView_PreviewKeyDown
together with:
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;
}
}
Also works fine.
With this solution you could, for example, create a custom behavior and attach it to your TreeView.
精彩评论