Reputation: 864
In WPF (MVVM, no code-behind), say I have the following xaml:
<StackPanel>
<Button>Normal 1</Button>
<Button>Special</Button> <!--This button should not tab focus, but still focus via arrow keys-->
<Button>Normal 2</Button>
</StackPanel>
By default, you can (1) tab between the buttons or (2) up/down arrow between the buttons. I want to make one of the buttons -- the Special button -- not focusable via tab, yet still focusable via up/down. I tried IsTabStop="False"
, but that also prevents focusing that button via directional navigation (up/down arrows).
How can I remove a single button from tab navigation, while continuing to allow directional navigation? Tabbing and arrowing should be unaffected for all other controls.
I've tried combinations of IsTabStop
, KeyboardNavigation.TabNavigation
, and KeyboardNavigation.DirectionalNavigation
to no avail. Maybe I haven't found the right mix. Or maybe there is another approach. Ideas?
EDIT: Okay, I am adding a bounty. To be clear, I am looking for a MVVM, no code-behind way to decorate a control (e.g. via style, attached property, attached behavior, etc), such that it is removed from the tab order, while remaining a valid directional navigation target. Hard coding knowledge of the controls into the Window (or similar), is not acceptable. This needs to be a general, reusable solution. Something like: <Button AllowDirectionalNavigationButPreventTabNavigation="True"/>
.
Upvotes: 4
Views: 8230
Reputation: 734
How about that option. You stick your special button into another container and put KeyboardNavigation.TabNavigation="None" on that container. I've just tried it and it looks like I can achieve what you need.
<StackPanel >
<Button>Normal 1</Button>
<StackPanel KeyboardNavigation.TabNavigation="None">
<Button>Special</Button><!--This button should not tab focus, but still focus via arrow keys-->
</StackPanel>
<Button>Normal 2</Button>
</StackPanel>
Upvotes: 12
Reputation: 9944
here how i did it :
<Window x:Class="MvvmLight1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
mc:Ignorable="d ignore"
Height="300"
Width="300"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<command:EventToCommand Command="{Binding Mode=OneWay,Path=KeyDownCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid x:Name="LayoutRoot">
<StackPanel>
<Button>Normal 1</Button>
<Button>Special</Button>
<!--Should not tab focus, yet still focus via arrow keys-->
<Button>Normal 2</Button>
</StackPanel>
</Grid>
i am using the mvvmlight, and the EventToCommand is used to intercept the KeyDown Event and direct it to the following command in the ViewModel:
private RelayCommand<KeyEventArgs> _keyDownCommand;
public RelayCommand<KeyEventArgs> KeyDownCommand
{
get
{
return _keyDownCommand
?? (_keyDownCommand = new RelayCommand<KeyEventArgs>(
(s) =>
{
if (s.Key == Key.Tab)
{
s.Handled = true;
}
}));
}
}
Upvotes: 0