12

From what I have read, there appears to be no functionality to achieve an underline for TextBlocks or HyperlinkButtons or the like in Windows RT, which appears ludicrous, but anyway, does anybody have an elegant approach to tackling this, specifically to create a link which runs a Click event or binding command?

As you can see out-of-the-box support doesn't appear to exist: http://social.msdn.microsoft.com/Forums/en-CA/winappswithcsharp/thread/cba0c363-60da-4e

GONeale
  • 26,302
  • 21
  • 106
  • 149
  • As @Soheil's answer shows, it's quiet easy to achieve underlines in both cases. And if you consider the underlying "Modern UI" design principle to reduce clutter, then it actually does not seem ludicrous that hyperlinks are not underlined by default. – HappyNomad Sep 28 '13 at 06:02

4 Answers4

18

This is how I've solved this problem before.

<HyperlinkButton x:Name="ExamplesLink" Click="ExamplesLink_Click"
   Extensions:FrameworkElementExtensions.SystemCursor="Hand">
   <TextBlock>
      <Underline>
        <Run Text="Examples"/>
      </Underline>
   </TextBlock>
</HyperlinkButton>

If you have the WinRT XAML toolkit you can set your cursor with the extension like above as well.

Soheil
  • 196
  • 3
  • 1
    Simple, elegant and exactly what I was looking for! – c0D3l0g1c Feb 06 '13 at 17:16
  • Bit late to the party, but great solution! Thanks! One note to make when I implemented this: I'm not using WinRT XAML toolkit, but the `HyperlinkButton` still changed the cursor to `Hand` by default. – Geoff James Feb 08 '17 at 11:22
9

If you need (as in my case) to template the HyperlinkButton, keeping your bindings in your view, in you can do that in this way:

<Style TargetType="HyperlinkButton"
    x:Key="StandardHyperlinkButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <TextBlock Style="{StaticResource BaseEntityDetailTextStyle}">
                    <Underline>
                        <Run Text="{Binding Path=Content, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
                    </Underline>
                </TextBlock>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

...and then in your XAML view, for example:

<HyperlinkButton Style="{StaticResource StandardHyperlinkButton}"
    Content="{Binding Path=myContent, Mode=OneWay}"
    Command="{StaticResource myCommand}"
    CommandParameter="{Binding Path=myContent, Mode=OneWay}" />

In this way you can also solve @sacha problem with bindings!

MAXE
  • 4,978
  • 2
  • 45
  • 61
  • 3
    Yep that looks good. Keeps everyone happy. Stuff in Styles where it should be, and binding in view where it should be. This is correct answer in my opinion – sacha barber Oct 18 '13 at 13:39
1

You can use a RichTextBlock with embedded HyperlinkButtons. If you look at RichTextBlockExtensions - you can use it to bind html text fragments (with anchor tags) to automatically populate a RichTextBlock with a linked text setup.

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
0

The problem with the above Hyperlinkbutton, AFAIK is that the Run Text is not bindable, so you end up having to repeat that TextBlock/Underline/Run pattern for every hyperlink button. Far better would be to make it a style.

For example if you try this, it will not work and an UnhandledException occurs

<HyperlinkButton Width="Auto" Height="Auto" Margin="2" 
        Content="{Binding DoctorName}"
        Command="{Binding ElementName=scheduleView, 
            Path=DataContext.NavigateToAppointmentsDetailCommand}"
        CommandParameter="{Binding DoctorName}">
    <HyperlinkButton.Template>
        <ControlTemplate>
            <TextBlock>
                <Underline>
                <Run Text="{TemplateBinding Content}"/>
                </Underline>
            </TextBlock>
        </ControlTemplate>
    </HyperlinkButton.Template>

</HyperlinkButton>

The only way I found to fix this where the hyperlink text was also bindable was to use a fake underline rectangle and a regular button. I then show the underline (fake rectangle) based on whether the Pointer is over the button. Here is the relevant code:

Not the best solution but it is bindable for the content (link text), and its a generic solution.

<Button Width="Auto" Height="Auto" Margin="2" 
        Style="{StaticResource HyperLinkButtonStyle}"
        Content="{Binding DoctorName}">
</Button>

                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames 
                    Storyboard.TargetProperty="(UIElement.Visibility)" 
                    Storyboard.TargetName="rect">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>

                                </Storyboard>

                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates"/>
                    </VisualStateManager.VisualStateGroups>
                    <StackPanel Orientation="Vertical">
                        <TextBlock x:Name="txt" 
                Text="{TemplateBinding Content}" 
                HorizontalAlignment="Center" 
                                    FontFamily="Segoe UI" FontSize="18" FontWeight="Thin"/>
                        <Rectangle x:Name="rect" Fill="White" Height="2" Visibility="Collapsed"
                            VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
                    </StackPanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
sacha barber
  • 2,214
  • 1
  • 24
  • 37
  • You are thinking of an *old* version of WPF. `Run`s are perfectly bindable in a Windows Store app. – HappyNomad Sep 28 '13 at 05:53
  • Did not seem to be able to Bind the Run inside a button template when I was doing it on Win8 store app. Got a working example of that for Win8 store app, say inside a style so it binds to the Button Content property. Perhaps Template binding doesn't work – sacha barber Oct 02 '13 at 14:41
  • You might want to post your example to [Microsoft Connect](https://connect.microsoft.com/) so that it eventually gets fixed. – HappyNomad Oct 02 '13 at 21:45