Focus and TabIndex on UserControls

2020-07-10 10:55发布

问题:

I have a strange behaviour: I have a MainWindow containing textboxes and (simple) usercontrols (textbox and button), but I stripped this to only a textbox for debug purposes.

When I use textboxes and usercontrols WITHOUT setting a TabIndex property the cursor steps through the controls in right order (in the order the controls are added to the window)

When I use textboxes and usercontrols WITH setting a TabIndex property the cursor steps through the controls in invalid order (first all usercontrols, then all textboxes), this is also true when the TabIndex is set to value corresponding to the order in which the control was added

Here is my usercontrol

<UserControl x:Class="SmallControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             >
        <TextBox x:Name="txTEXT" Text="{Binding Text}" />
</UserControl>

The following Mainwindow xaml leads to order 000000,111111,222222,333333 ,thats ok

    <GroupBox Header="Small,Textbox,Small,TextBox without TabIndex">
        <UniformGrid Columns="4">
            <local:SmallControl Text="000000" />
            <TextBox Text="111111" />
            <local:SmallControl Text="222222" />
            <TextBox Text="333333" />
        </UniformGrid>
    </GroupBox>

The following Mainwindow xaml leads to order 000000,222222,111111,333333, thats NOT ok

    <GroupBox Header="Small,Textbox,Small,TextBox with TabIndex">
        <UniformGrid Columns="4">
            <local:SmallControl TabIndex="0" Text="000000" />
            <TextBox TabIndex="1" Text="111111" />
            <local:SmallControl TabIndex="2" Text="222222" />
            <TextBox TabIndex="3" Text="333333" />
        </UniformGrid>
    </GroupBox>

Is there a way to use TabIndex without beeing forced to add controls in the "right" order in XAML?

回答1:

By default, WPF reads all the controls, both inside and outside UserControls, at the same tab level (unless specified otherwise). Since the controls inside the UserControl do not have a TabIndex specified, they get tabbed to last after the first tab cycle.

To change this behavior I usually set IsTabStop="False" on my UserControl definition, then I bind the inner controls TabIndex to the UserControl's TabIndex

UserControl XAML

<TextBox x:Name="txTEXT" Text="{Binding Text}" 
         TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource 
             AncestorType={x:Type local:SearchView}}}"/>

Usage XAML

<GroupBox Header="Small,Textbox,Small,TextBox with TabIndex">
    <UniformGrid Columns="4">
        <local:SmallControl TabIndex="0" Text="000000" IsTabStop="False" />
        <TextBox TabIndex="1" Text="111111" />
        <local:SmallControl TabIndex="2" Text="222222" IsTabStop="False" />
        <TextBox TabIndex="3" Text="333333" />
    </UniformGrid>
</GroupBox>

You might also be able to get it tabbing correctly by setting the KeyboardNavigation.TabNavigation attached property on your UserControl to Local. I seem to recall having issues with this, but I honestly can't remember the details, so it might work.

<UserControl x:Class="SmallControl" ...
             KeyboardNavigation.TabNavigation="Local"  />