locked
How do I make Hyperlinks in RichTextBlock not be completely unaligned? RRS feed

  • Question

  • I want to be able to show a hyperlink in a RichTextBlock element, but I also want it to look right. The closest I've been able to get to is this:



    The XAML for this is pasted below - essentially, I use `InlineUIElement` and I edited the resource to remove all the crud around the button. Am I missing something? Is the only real way to solve this is to roll my own hyperlink?

    Here's the XAML for the rich text block:

     <RichTextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14">
      <Paragraph>I just want this
       <InlineUIContainer>
        <HyperlinkButton Style="{StaticResource HyperlinkButtonStyle1}">Hyperlink</HyperlinkButton>
       </InlineUIContainer>
       to not look like crap
      </Paragraph>
     </RichTextBlock>

    And here's the XAML for the nuked resource:

     <Style x:Key="HyperlinkButtonStyle1" TargetType="HyperlinkButton">
      <Setter Property="Foreground" Value="{StaticResource HyperlinkForegroundThemeBrush}"/>
      <Setter Property="Background" Value="{StaticResource HyperlinkButtonBackgroundThemeBrush}"/>
      <!--<Setter Property="BorderBrush" Value="{StaticResource HyperlinkButtonBorderThemeBrush}"/>-->
      <Setter Property="BorderThickness" Value="0"/>
      <Setter Property="Padding" Value="0"/>
      <Setter Property="HorizontalAlignment" Value="Left"/>
      <Setter Property="VerticalAlignment" Value="Bottom"/>
      <Setter Property="FontFamily" Value="Global User Interface"/>
      <Setter Property="FontSize" Value="14"/>
      <Setter Property="Template">
       <Setter.Value>
        <ControlTemplate TargetType="HyperlinkButton">
         <Grid>
          <VisualStateManager.VisualStateGroups>
           <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal"/>
            <VisualState x:Name="PointerOver">
             <Storyboard>
              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
               <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkPointerOverForegroundThemeBrush}"/>
              </ObjectAnimationUsingKeyFrames>
             </Storyboard>
            </VisualState>
            <VisualState x:Name="Pressed">
             <Storyboard>
              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
               <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkPressedForegroundThemeBrush}"/>
              </ObjectAnimationUsingKeyFrames>
             </Storyboard>
            </VisualState>
            <VisualState x:Name="Disabled">
             <Storyboard>
              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
               <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkDisabledThemeBrush}"/>
              </ObjectAnimationUsingKeyFrames>
             </Storyboard>
            </VisualState>
           </VisualStateGroup>
           <VisualStateGroup x:Name="FocusStates">
            <VisualState x:Name="Focused">
             <Storyboard>
              <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
              <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
             </Storyboard>
            </VisualState>
            <VisualState x:Name="Unfocused"/>
            <VisualState x:Name="PointerFocused"/>
           </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" VerticalAlignment="Bottom">
           <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalAlignment="Bottom"/>
          </Border>
          <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
          <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
         </Grid>
        </ControlTemplate>
       </Setter.Value>
      </Setter>
     </Style>


    Shahar Prish Blog: http://blogs.msdn.com/CumGranoSalis Professional Excel Services: http://www.amazon.com/Professional-Excel-Services-Programmer/dp/0470104864


    Saturday, October 13, 2012 7:16 PM

Answers

  • I had exactly the same problem as you, but I've finally managed to solve it. You need to set all Padding and BorderThickness in HyperlinkButton's template to 0 AND set HyperlinkButton's bottom margin to -4 or something like that, depending on the Font size you are using.

    Here's template that I'm using and it works for me

    <Style x:Key="NoMarginHyperlinkButtonStyle" TargetType="HyperlinkButton">
                    <Setter Property="Foreground" Value="{StaticResource HyperlinkForegroundThemeBrush}"/>
                    <Setter Property="Background" Value="{StaticResource HyperlinkButtonBackgroundThemeBrush}"/>
                    <Setter Property="BorderBrush" Value="{StaticResource HyperlinkButtonBorderThemeBrush}"/>
                    <Setter Property="BorderThickness" Value="0"/>
                    <Setter Property="Padding" Value="0"/>
                    <Setter Property="Margin" Value="0,0,0,-4"/>
                    <Setter Property="HorizontalAlignment" Value="Left"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
                    <Setter Property="FontWeight" Value="SemiBold"/>
                    <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="HyperlinkButton">
                                <Grid>
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal"/>
                                            <VisualState x:Name="PointerOver">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkPointerOverForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Pressed">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkPressedForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Disabled">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkDisabledThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="FocusStates">
                                            <VisualState x:Name="Focused">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Unfocused"/>
                                            <VisualState x:Name="PointerFocused"/>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                        <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    </Border>
                                    <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
                                    <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>

    • Marked as answer by Jesse Jiang Tuesday, October 30, 2012 7:54 AM
    Sunday, October 14, 2012 4:24 PM

All replies

  • You can adjust the Margins on the Border element in your template to drop it down inline with the text.

    --Rob

    Saturday, October 13, 2012 7:35 PM
    Moderator
  • That has no noticeable effect on the UI. It stays as unaligned.

    Shahar Prish Blog: http://blogs.msdn.com/CumGranoSalis Professional Excel Services: http://www.amazon.com/Professional-Excel-Services-Programmer/dp/0470104864

    Sunday, October 14, 2012 10:53 AM
  • I had exactly the same problem as you, but I've finally managed to solve it. You need to set all Padding and BorderThickness in HyperlinkButton's template to 0 AND set HyperlinkButton's bottom margin to -4 or something like that, depending on the Font size you are using.

    Here's template that I'm using and it works for me

    <Style x:Key="NoMarginHyperlinkButtonStyle" TargetType="HyperlinkButton">
                    <Setter Property="Foreground" Value="{StaticResource HyperlinkForegroundThemeBrush}"/>
                    <Setter Property="Background" Value="{StaticResource HyperlinkButtonBackgroundThemeBrush}"/>
                    <Setter Property="BorderBrush" Value="{StaticResource HyperlinkButtonBorderThemeBrush}"/>
                    <Setter Property="BorderThickness" Value="0"/>
                    <Setter Property="Padding" Value="0"/>
                    <Setter Property="Margin" Value="0,0,0,-4"/>
                    <Setter Property="HorizontalAlignment" Value="Left"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
                    <Setter Property="FontWeight" Value="SemiBold"/>
                    <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="HyperlinkButton">
                                <Grid>
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal"/>
                                            <VisualState x:Name="PointerOver">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkPointerOverForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Pressed">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkPressedForegroundThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Disabled">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HyperlinkDisabledThemeBrush}"/>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="FocusStates">
                                            <VisualState x:Name="Focused">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Unfocused"/>
                                            <VisualState x:Name="PointerFocused"/>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                        <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    </Border>
                                    <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
                                    <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>

    • Marked as answer by Jesse Jiang Tuesday, October 30, 2012 7:54 AM
    Sunday, October 14, 2012 4:24 PM