Search code examples
wpfexpanderkeyboard-navigation

How can I set the TabIndex on a WPF Expander control?


In this example window, tabbing through goes from the first textbox, to the last textbox and then to the expander header.

<Window x:Class="ExpanderTab.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    FocusManager.FocusedElement="{Binding ElementName=FirstField}">
    <StackPanel>
        <TextBox TabIndex="10" Name="FirstField"></TextBox>
        <Expander TabIndex="20" Header="_abc">
            <TextBox TabIndex="30"></TextBox>
        </Expander>
        <TextBox TabIndex="40"></TextBox>
    </StackPanel>
</Window>

Obviously, I'd like this to go First text box, expander header, then last textbox. Is there an easy way to assign a TabIndex to the header of the expander?

I've tried forcing the expander to be a tabstop using KeyboardNavigation.IsTabStop="True", but that makes the whole expander get focus, and the whole expander doesn't react to the spacebar. After two more tabs, the header is again selected and I can open it with the spacebar.

Edit: I'll throw a bounty out there for anyone who can come up with a cleaner way to do this - if not, then rmoore, you can have the rep. Thanks for your help.


Solution

  • The following code will work even without the TabIndex properties, they are included for clarity about the expected tab order.

    <Window x:Class="ExpanderTab.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" FocusManager.FocusedElement="{Binding ElementName=FirstField}">
        <StackPanel>
            <TextBox TabIndex="10" Name="FirstField"></TextBox>
            <Expander TabIndex="20" Header="Section1" KeyboardNavigation.TabNavigation="Local">
                <StackPanel KeyboardNavigation.TabNavigation="Local">
                    <TextBox TabIndex="30"></TextBox>
                    <TextBox TabIndex="40"></TextBox>
                </StackPanel>
            </Expander>
            <Expander TabIndex="50" Header="Section2" KeyboardNavigation.TabNavigation="Local">
                <StackPanel KeyboardNavigation.TabNavigation="Local">
                    <TextBox TabIndex="60"></TextBox>
                    <TextBox TabIndex="70"></TextBox>
                </StackPanel>
            </Expander>
            <TextBox TabIndex="80"></TextBox>
        </StackPanel>
    </Window>