I find that the KeyboardNavigation does not work as I would expect as it pertains to Ctrl-Tab and a TabControl. I put together a simple prototype and KeyboardNavigation.ControlTabNavigation="None"
just does not seem to have the expected impact on the switching of Tabs using Ctrl-Tab, once I left-click a tab and the keyboard focus is within the TabControl.
However, using InputBindings with a Command can override the unwanted Ctrl-Tab default behavior. From there, I found that KeyboardNavigation.TabNavigation="Cycle"
, as well as the other the other options for TabNavigation seem to behave reasonably. Using The FocusManager and other techniques described in the resource links below should allow one to obtain desired keyboard navigation, albeit using somewhat counter-intuitive techniques.
The InputBindings do have to be set for each control that has the unwanted default behavior, although a more sophisticated solution might walk the visual tree to set the InputBindings for all controls of a certain type, for example. I found having the Command simply do nothing neutralizes the key sequence adequately. In my example, I display a dialog box for testing.
Note, below Command binding requires you target WPF 4.0; please see resources at end of post for resource on how to target WPF 3.5 or earlier
In XAML:
<TabControl
x:Name="tabControl1"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedTabItem}"
ItemsSource="{Binding TabItemViewModels}"
KeyboardNavigation.ControlTabNavigation="None"
KeyboardNavigation.TabNavigation="Continue">
<TabControl.InputBindings>
<KeyBinding Modifiers="Control"
Key="Tab"
Command="{Binding ShowDialogCommand}" />
</TabControl.InputBindings>
</TabControl>
Note, in above XAML, KeyboardNavigation.ControlTabNavigation="None"
is of no effect and can be eliminated.
In backing DataContext, typically a ViewModel:
Declare your binding property:
public RelayCommand ShowDialogCommand
{
get;
private set;
}
Initialize the property; for example, can be in the constructor of the ViewModel (Note, RelayCommand is from MVVM-Light library.):
ShowDialogCommand = new RelayCommand(() =>
{
MessageBox.Show("Show dialog box command executed", "Show Dialog Box Command", MessageBoxButton.OK, MessageBoxImage.Information);
});
Resources:
Helpful StackOverflow post on KeyBindings
More detail on KeyBinding to a Command; describes special CommandReference technique needed if targeting WPF framewrok 3.5 or earlier
Microsoft's Focus Overview