Reputation: 132548
Why isn't my XAML following the TabOrder I specified?
I currently have:
<DockPanel>
<Grid DockPanel.Dock="Top">
<UserControl TabIndex="0">
<StackPanel Orientation="Horizontal">
<ComboBox />
<TextBox Text="Search Text" />
<Button Content="Search" />
</StackPanel>
</UserControl>
<ComboBox TabIndex="1" />
<Separator />
<TextBox TabIndex="3" Text="Save" />
<TextBox TabIndex="4" Text="Cancel" />
</Grid>
<Grid>
<ContentControl TabIndex="2" />
<Popup />
</Grid>
</DockPanel>
My TabOrder should go
But instead it goes
What do I have wrong with my TabOrder?
Edit
I found this SO answer which suggested making UserControl.IsTabStop="False"
, and binding it's Child control's TabIndex to UserControl.TabIndex
, which partially works.
My TabOrder is now
Upvotes: 5
Views: 6104
Reputation: 132548
Apparently by default, WPF reads all the controls, 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.
The workaround was to bind the TabIndex
of the inner controls to the TabIndex
of the UserControl
<DockPanel Margin="10" KeyboardNavigation.TabNavigation="Cycle">
<Grid DockPanel.Dock="Top"
local:GridProperties.ColumnCount="6"
local:GridProperties.StarColumns="0">
<TextBlock Text="Header" FontSize="20" FontWeight="Bold" />
<ContentControl Grid.Column="1" TabIndex="0" IsTabStop="False" Content="{Binding SearchViewModel}" />
<ComboBox Grid.Column="2" Margin="5" Width="100" />
<Separator Grid.Column="3" Style="{StaticResource VerticalSeparatorStyle}" />
<Button Grid.Column="4" TabIndex="3" Content="Save" Width="75" Margin="5" />
<Button Grid.Column="5" TabIndex="4" Content="Cancel" Width="75" Margin="5" />
</Grid>
<Line HorizontalAlignment="Stretch" X2="1" Stretch="Fill" Stroke="Black" StrokeThickness="1" Margin="0,5" DockPanel.Dock="Top" />
<Grid x:Name="ShellContentRoot">
<!-- Current Page -->
<ContentControl TabIndex="2" Content="{Binding CurrentAccount}" IsTabStop="False" />
<!-- Search Results -->
<local:PopupPanel local:PopupPanel.PopupParent="{Binding ElementName=ShellContentRoot}" />
</Grid>
</DockPanel>
The only thing special about my SearchView
is that the controls all set
TabIndex="{Binding Path=TabIndex, RelativeSource={RelativeSource
AncestorType={x:Type local:SearchView}}}"
Tab Order goes:
Upvotes: 3
Reputation: 2129
This works for me:
<DockPanel >
<DockPanel DockPanel.Dock="Top">
<UserControl TabIndex="0" KeyboardNavigation.TabNavigation="Local" DockPanel.Dock="Left">
<StackPanel Orientation="Horizontal">
<ComboBox />
<TextBox Text="Search Text" />
<Button Content="Search" />
</StackPanel>
</UserControl>
<ComboBox TabIndex="1" DockPanel.Dock="Left" />
<Separator />
<TextBox TabIndex="3" Text="Save" DockPanel.Dock="Left"/>
<TextBox TabIndex="4" Text="Cancel" DockPanel.Dock="Left"/>
</DockPanel>
<Grid DockPanel.Dock="Bottom">
<ContentControl TabIndex="2" Height="100" Width="100"/>
<Popup />
</Grid>
</DockPanel>
Upvotes: 0
Reputation: 2129
Try including KeyboardNavigation.TabNavigation="Local" in your parent DockPanel.
<DockPanel KeyboardNavigation.TabNavigation="Local">
Upvotes: 0