WPF: navigation tab is broken with collapsed hyperlink

Problem: TAB key navigation stops when minimizing 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” text box. Navigation works as expected when TextBlock hypertext is displayed.

Question: How to configure TAB navigation when minimizing HyperLink?

+7
source share
2 answers

The problem is not Hyperlink, but nested controls in TextBlock. You can change it to

 <TextBlock Visibility="Collapsed"> <TextBlock Text="MyText" /> </TextBlock> 

and Tab navigation will still be broken.

The solution is to use KeyboardNavigation.TabNavigation="Once" in an external 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 as intended. The problem is that the internal TextBlock gets Focus, even if the external control crashes. Setting KeyboardNavigation.TabNavigation to Once solves it, since the entire container and its children receive focus only once. ( MSDN )

+8
source

@Gimno's answer put me on the right track, but I found that using KeyboardNavigation.TabNavigation="None" actually gives focus to the top element only once (as you would expect from Once ). Gimno's answer works because it also set Focusable="False" in the hyperlink. With TabNav = None, you do not need to set Focusable for all child controls.

Here is my application of this method (only the button gets the focus of the tab, not the text block or 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> 
+2
source

All Articles