Sybren
Sybren

Reputation: 1079

Prevent tabbing to TextBlock when Visibility is Collapsed

I'am trying to create a trigger which removes a TextBlock from the tab navigation when the Visibility is Collapsed.

This is the style:

 <Style x:Uid="Style_1" TargetType="TextBlock">
    <Setter x:Uid="Setter_1" Property="TextOptions.TextFormattingMode" Value="{StaticResource TextFormattingMode}"/> 
    <Setter x:Uid="Setter_32" Property="TextOptions.TextRenderingMode" Value="{StaticResource TextRenderingMode}"/>
    <Setter x:Uid="Setter_2" Property="TextBlock.FontFamily" Value="{StaticResource FontFamily}"/>
    <Setter x:Uid="Setter_3" Property="SnapsToDevicePixels" Value="True"/>
    <Setter x:Uid="Setter_4" Property="VerticalAlignment" Value="Center"/>
    <Setter x:Uid="Setter_74" Property="UseLayoutRounding" Value="True"/>
    <Setter x:Uid="Setter_5" Property="Foreground" Value="{StaticResource LabelForeground}"/>
    <Setter x:Uid="Setter_7" Property="FontSize" Value="{StaticResource FontSize}"/>
    <Style.Triggers>
        <DataTrigger x:Uid="DataTrigger_2" Binding="{Binding Source={x:Static cs:ZoomLevel.Instance}, Path=ActualZoomLevelIsDefault}" Value="False">
            <Setter x:Uid="Setter_33" Property="TextOptions.TextFormattingMode" Value="Ideal"/>                     
        </DataTrigger>
        <DataTrigger x:Uid="DataTrigger_100" Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Visibility}" Value="Collapsed">
            <!--<Setter Property="IsEnabled" Value="False"/>-->
            <!--<Setter Property="Control.IsTabStop" Value="False"/>-->
            <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
            <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

But the TextBlock still gains the focus if I tab to it. IsKeyboardFocusWithin is true when I focus to the TextBlock. I can set IsEnabled to false in my trigger to make it work, but I wonder why the attached property is not working. So my question is: why is the KeyboardNavigation property not working?

Example:

<TextBlock x:Uid="TextBlock_2" Grid.Column="1" Grid.Row="1" Margin="3,3,0,0" HorizontalAlignment="Right" Visibility="Collapsed">          
       <Hyperlink x:Uid="Hyperlink_2" Command="{Binding SelectRoutingMethods}"> 
           <Run x:Uid="Run_2" Text="{Binding ContactPreferences}"/>
       </Hyperlink>
</TextBlock>

The TextBlock is tabable but still visible in my example.

Upvotes: 0

Views: 334

Answers (3)

Gopichandar
Gopichandar

Reputation: 2832

As answered by @Shadowed, it was Hyperlink that is getting the Focus. Not sure why this is happening as the Content should not get Focusif the parent is in Collapsed state.

Anyway, I can give you workaround for this.

 <StackPanel>
    <StackPanel.Resources>
        <local:VisibilitytoFocusConverter x:Key="VisibilitytoFocusConv" />
    </StackPanel.Resources>
    <TextBox >Temp</TextBox>
    <TextBlock Visibility="Collapsed" Height="20" KeyboardNavigation.TabNavigation ="{Binding Visibility, RelativeSource={RelativeSource Self}, Converter={StaticResource VisibilitytoFocusConv}}">
        <Hyperlink Command="{Binding AddOptionalAddressCommand}" />
    </TextBlock>
    <TextBox >Temp</TextBox>
</StackPanel>

Converter:

public class VisibilitytoFocusConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo language)
    {
        return ((Visibility)value) == Visibility.Visible ? "Local" : "None";
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language)
    {
        return new NotFiniteNumberException();
    }
}

Hope that helps.

Upvotes: 0

grek40
grek40

Reputation: 13438

Credits to @Shadowed for finding the issue with hyperlink.

Here is my alternativ solution: set the KeyboardNavigation.IsTabStop on Hyperlink based on the next UIElement visibility up the tree (which will be the TextBlock in this specific case.

<Hyperlink x:Uid="Hyperlink_2" KeyboardNavigation.IsTabStop="{Binding IsVisible,RelativeSource={RelativeSource AncestorType={x:Type UIElement}}}"> 

Upvotes: 0

Shadowed
Shadowed

Reputation: 966

It's not your TextBlock that gets the focus. It's Hyperlink. I don't know why, it's not even in Visual Tree but it does. It seems like a bug. If you set its property Focusable to false it wont take focus anymore.

Here is complete simplified example:

    <Window.Resources>
      <Style TargetType="TextBlock">
      <Setter Property="Focusable" Value="True" />
      <Style.Triggers>
          <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Visibility}" Value="Collapsed">
            <Setter Property="Focusable" Value="False"/>
          </DataTrigger>
        </Style.Triggers>
      </Style>
  </Window.Resources>
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="*"/>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBox>Temp</TextBox>
    <TextBlock Visibility="Visible" Grid.Row="1">
        <Hyperlink Focusable="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TextBlock}, Path=Focusable}" Command="{Binding AddOptionalAddressCommand}">test</Hyperlink>
    </TextBlock>
    <TextBox Grid.Row="2" >Temp</TextBox>
  </Grid>

Upvotes: 1

Related Questions