Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: Tab navigation broken with collapsed hyperlink

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?

like image 878
Helge Klein Avatar asked Mar 28 '11 15:03

Helge Klein


2 Answers

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)

like image 188
Gimno Avatar answered Nov 20 '22 07:11

Gimno


@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>
like image 32
Pat Avatar answered Nov 20 '22 05:11

Pat