wpffocustabbingkeyboard-navigation

How to prevent tab navigation to a control, while allowing directional navigation to that control


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"/>.


Solution

  • 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>