Reputation: 97708
I'm writing an app that uses the "tabbed browsing" metaphor, with a TabControl the full size of the window, and other stuff inside the tabs. Sometimes those tabs will themselves contain other TabControls.
(Tabs inside tabs can be confusing, so I'll re-style the inner TabControl so it doesn't look like a TabControl. I'll probably style it to use ToggleButtons at the top instead of tabs.)
I want this UI to behave like you would expect the tabbed-browsing metaphor to work: Ctrl+Tab should always switch tabs on the outer TabControl (the one that looks like a TabControl), even if keyboard focus is inside the inner TabControl (which doesn't look like a TabControl, and therefore shouldn't be expected to respond to Ctrl+Tab). But, of course, the inner TabControl gets the key event first and handles it itself.
What's the best way to keep the inner TabControl from responding to the Ctrl+Tab and Ctrl+Shift+Tab key events, so those events can bubble up to the outer TabControl?
Upvotes: 2
Views: 2881
Reputation: 1601
As an alternative to creating a Custom Control as suggested here, you could create an "Attached behaviour" to encapsulate this:
namespace WpfApplication1
{
using System.Windows;
using System.Windows.Input;
public static class IgnoreCtrlTabBehaviour
{
//Setter for use in XAML: this "enables" this behaviour
public static void SetEnabled(DependencyObject depObj, bool value)
{
depObj.SetValue(EnabledProperty, value);
}
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool),
typeof(IgnoreCtrlTabBehaviour),
new FrameworkPropertyMetadata(false, OnEnabledSet));
static void OnEnabledSet(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
{
var uiElement = depObj as UIElement;
uiElement.PreviewKeyDown +=
(object _, System.Windows.Input.KeyEventArgs e) =>
{
if (e.Key == Key.Tab &&
(Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
e.Handled = true;
}
};
}
}
}
Use in XAML like this:
<Window x:Class="WpfApplication1.MainWindow"
...
xmlns:local="clr-namespace:WpfApplication1"
...
<TabControl local:IgnoreCtrlTabBehaviour.Enabled="True">
<TabItem Header="tab1">
...
Upvotes: 1
Reputation: 3500
You can handle the PreviewKeyDown event on your inner TabControl and set e.Handled = true to prevent it from handling key events. You can then find the parent TabControl (perhaps recursively through ((TabControl)sender).Parent ) and change its SelectedIndex programmatically.
Wrapping that up in a custom control would keep it reasonably clean.
Upvotes: 1
Reputation: 12077
The WPF TabControl appears to manage the keyboard navigation feature via the OnKeyDown method. I would suggest creating a custom control that inherits from the TabControl, and override the OnKeyDown method.
Upvotes: 3