Problem: Navigation with the TAB key stops at collapsed TextBlock/Hyperlink.
Reproduction:
<Window x:Class="TabTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="200" Height="200">
<Grid>
<StackPanel Orientation="Vertical">
<TextBox Text="before" />
<TextBlock>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</TextBlock.Style>
<Hyperlink Focusable="False">
<TextBlock Text="test" />
</Hyperlink>
</TextBlock>
<TextBox Text="after" />
</StackPanel>
</Grid>
</Window>
If you run this super-simple demo and press TAB, the cursor moves to the "before" TextBox. Pressing TAB again does ... nothing. The cursor stays in the "before" TextBox and never reaches the "after" Textbox. Navigation works as expected when the Hyperlink's TextBlock is visible.
Question: How do I make TAB navigation work correctly with the HyperLink collapsed?
The problem is not the Hyperlink but the nested controls within the TextBlock. You could change it to
<TextBlock Visibility="Collapsed">
<TextBlock Text="MyText" />
</TextBlock>
and the Tab navigation would still be broken.
The solution is to use KeyboardNavigation.TabNavigation="Once"
at the outer TextBlock:
<TextBlock KeyboardNavigation.TabNavigation="Once">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</TextBlock.Style>
<Hyperlink Focusable="False">
<TextBlock Text="test" />
</Hyperlink>
</TextBlock>
then everything works the way as intended. The problem is that the inner TextBlock gets the Focus, even if the outer Control it is collapsed. Setting KeyboardNavigation.TabNavigation
to Once
solves it as the whole Container and its childs get the focus only once. (MSDN)
@Gimno's answer put me on the right track, but I found that using KeyboardNavigation.TabNavigation="None"
actually gives the top element focus only once (as you would expect from Once
). Gimno's answer works because he/she also set Focusable="False"
on the Hyperlink. With TabNav=None, you don't have to set Focusable on all the children controls.
Here's my application of this method (only the Button gets tab focus, not either textblock or the hyperlink):
<Button Command="{Binding ChangeSoundCommand}" Click="ChangeSoundClick" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Padding="0"
KeyboardNavigation.TabNavigation="None">
<Button.Template>
<ControlTemplate>
<Grid>
<TextBlock Name="tb" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" >
<Hyperlink>Browse...</Hyperlink>
</TextBlock>
<TextBlock Name="w_content" Text="{Binding FilePath}" TextTrimming="CharacterEllipsis" />
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="w_content" Property="Text" Value="">
<Setter TargetName="tb" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With