views:

58

answers:

2

It seems I can format a HyperlinkButton in the same way I can format a TextBlock:

HyperlinkButton hyperlinkButton = new HyperlinkButton();
hyperlinkButton.Content = "google";
hyperlinkButton.NavigateUri = new Uri("http://www.google.com");
hyperlinkButton.TargetName = "blank";
hyperlinkButton.Foreground = XamlHelpers.GetColorFromHex("555");
hyperlinkButton.TextDecoration = ... //error
hyperlinkButton.FontWeight = FontWeights.Bold;

However, TextDecoration doesn't work as it does in TextBlock. I get an automatic underline upon mouseover but would like it to have an underline before mouseover as well.

How can I add an underline to a HyperlinkButton in Silverlight?

+1  A: 

Edit the control template. I ripped this via Expression Blend.

 <Style x:Key="HyperlinkButtonStyle1" TargetType="HyperlinkButton">
            <Setter Property="Foreground" Value="#FF73A9D8"/>
            <Setter Property="Padding" Value="2,0,2,0"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="HyperlinkButton">
                        <Grid Background="{TemplateBinding Background}" Cursor="{TemplateBinding Cursor}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="UnderlineTextBlock">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="UnderlineTextBlock">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOverlay">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <TextBlock x:Name="UnderlineTextBlock" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Text="{TemplateBinding Content}" TextDecorations="Underline" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>                       
                            <TextBlock x:Name="DisabledOverlay" Foreground="#FFAAAAAA" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Text="{TemplateBinding Content}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Canvas.ZIndex="1"/>
                            <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            <Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Opacity="0" Stroke="#FF6DBDD1" StrokeThickness="1"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Change the visibility on this control:

<TextBlock x:Name="UnderlineTextBlock" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Text="{TemplateBinding Content}" TextDecorations="Underline" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>       
David
+4  A: 

If you just need a static underline (no mouseover effects) you should just use a TextBlock as the content of the HyperlinkButton. Since HyperlinkButton is a ContentControl it can take any other control type as it's content (more than just simple strings).

Here is some XAML which will get you an underlined TextBlock as the content for a HyperlinkButton:

    <HyperlinkButton NavigateUri="http://google.com"&gt;
        <TextBlock Text="Google" TextDecorations="Underline" />
    </HyperlinkButton>

You should be able to create your TextBlock and set the Content property of your HyperlinkButton with C# in code-behind as well if that is what you are doing.

As David said, editing the ControlTemplate will certainly work to style a HyperlinkButton to your liking, but using an actual underlined TextBlock as content may be simpler and a lot less XAML if that is all you need to do.

Dan Auclair
Yes, it works in code behind as well. In fact, I put the TextBlock inside a Border so that I can change the background color on mouse-over as well. This solution enables you to have full control of the hyperlink formatting (except the blue focus box). Thanks.
Edward Tanguay