Edward Tanguay
Edward Tanguay

Reputation: 193282

How to make a simple hyperlink in XAML?

All I want to do is make a little hyperlink in XAML. I've tried everything. I give up.

What is the syntax for this?

<StackPanel Width="70" HorizontalAlignment="Center">

    <Hyperlink Click="buttonClose_Click" Cursor="Hand" 
         Foreground="#555" Width="31" Margin="0 0 0 15"  
         HorizontalAlignment="Right">Close</Hyperlink>

    <Button Width="60" Margin="0 0 0 3">Test 1</Button>
    <Button Width="60" Margin="0 0 0 3">Test 2</Button>
    <Button Width="60" Margin="0 0 0 3">Test 3</Button>
    <Button Width="60" Margin="0 0 0 3">Test 4</Button>
</StackPanel>

Visual Studio Team: In Visual Studio 2010 I want Clippy to pop up and say "It seems you are trying to make a hyperlink" and tell me how to do it. Can't you do that with MEF? It would be retro cool, and these little "how do I do what I already know how to do in HTML" issues burn up so much time during the learning process with XAML.

Upvotes: 61

Views: 96187

Answers (8)

Nalan Madheswaran
Nalan Madheswaran

Reputation: 10562

Try this:

<TextBlock>
    <Hyperlink RequestNavigate="Hyperlink_RequestNavigate" 
               NavigateUri="http://www.msn.com">MSN</Hyperlink> 
</TextBlock>

private void Hyperlink_RequestNavigate(object sender,
                                       System.Windows.Navigation.RequestNavigateEventArgs e)
{
    System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}

Upvotes: 35

El0din
El0din

Reputation: 3370

in UWP with mvvmcross i'm using this

  <HyperlinkButton Content="{Binding TextSource, ConverterParameter=MyUrl, Converter={StaticResource Language},
           FallbackValue=_MyUrl}" NavigateUri="http://www.google.com" />

Upvotes: 0

VampireMonkey
VampireMonkey

Reputation: 177

<TextBlock>
  <Hyperlink NavigateUri="{Binding YourUri}" RequestNavigate="YourRequestNavigate">
   <TextBlock Text="{Binding YourText}" />
  </Hyperlink>
</TextBlock>

This will linkify any binded text in the nested textblock, i have not found a better way yet, i would like the first textblock to not be there if possible. This will work for DataTemplates aswell.

Upvotes: 9

Spaso Lazarevic
Spaso Lazarevic

Reputation: 906

You can simply use HyperlinkButton. When it is clicked on, the URL will be displayed in your web browser:

<HyperlinkButton
    NavigateUri="https://dev.windowsphone.com"
    TargetName="_blank"
    Content="Windows Phone Dev Center" />

Upvotes: 2

Brett Ryan
Brett Ryan

Reputation: 28255

You may find that if you're binding to anything other than simple text values you will need to use ContentPresenter otherwise nothing will appear, this could be true if you're binding to an XML data source.

A Property Trigger for IsMouseOver gives the text an underline.

An example where I"m binding to XML is presented below.

<Style x:Key="JobNumberStyleButton" TargetType="{x:Type Button}">
  <Setter Property="VerticalAlignment" Value="Top"/>
  <Setter Property="HorizontalAlignment" Value="Left"/>
  <Setter Property="Cursor" Value="Hand"/>
  <Setter Property="Background" Value="Transparent"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <TextBlock>
          <ContentPresenter
            Margin="0,0,0,0"
            ContentTemplate="{TemplateBinding ContentTemplate}"
            Content="{TemplateBinding Content}"
            ContentStringFormat="{TemplateBinding ContentStringFormat}"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
            RecognizesAccessKey="False"
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </TextBlock>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Button">
            <TextBlock Padding="0,0,0,0" Margin="0,0,0,0">
              <Underline>
                <ContentPresenter
                  Margin="0,0,0,0"
                  ContentTemplate="{TemplateBinding ContentTemplate}"
                  Content="{TemplateBinding Content}"
                  ContentStringFormat="{TemplateBinding ContentStringFormat}"
                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                  RecognizesAccessKey="False"
                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
              </Underline>
            </TextBlock>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Trigger>
  </Style.Triggers>
</Style>

Upvotes: 4

Joe White
Joe White

Reputation: 97656

You can't add a Hyperlink to a StackPanel -- you'll get a runtime error. (Actually, I'm kinda surprised it's not a compile-time error.) That's because Hyperlink doesn't live in the "controls" side of WPF with <Button> and <StackPanel> and other things that are laid out on rectangular chunks of screen and descend from UIElement. Instead, it lives in the "text" side of things, with <Bold> and <Run> and <Paragraph> and other generally texty things that word-wrap and flow in lines and paragraphs and descend from TextElement.

Once you realize that there are two separate class hierarchies with different layout behaviors, it makes sense that Hyperlink would be on the "text" side of things (makes it easy to e.g. have a paragraph with a hyperlink in the middle, and even for that hyperlink to wrap across a line break).

But no, it's not so discoverable when you're starting out.

To mix the two worlds, and use a hyperlink as a control, all you need to do is put it in a TextBlock. TextBlock is a control-ish thing (i.e., can go in a StackPanel) that contains text-ish things (i.e., can contain a Hyperlink):

<TextBlock><Hyperlink Click="buttonClose_Click">Close</Hyperlink></TextBlock>

Upvotes: 174

Nir
Nir

Reputation: 29584

You can use a Button with a custom control template, the code below is a limited hyperlink style button (for example it only support textual hyperlinks) but maybe it'll point you in the right direction.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="Link" TargetType="Button">
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Foreground" Value="Blue"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <TextBlock TextDecorations="Underline" 
                    Text="{TemplateBinding Content}"
                    Background="{TemplateBinding Background}"/>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Foreground" Value="Red"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</Page.Resources>
<Button Content="Click Me!" Style="{StaticResource Link}"/>
</Page>

Upvotes: 38

Stefano Driussi
Stefano Driussi

Reputation: 2261

Usually, the meaning of an Hyperlink is to give an anchor to send the user to another Page or generally speaking to another resource, so it's implemented in such a way and you have to specify the location for that resource like this:

<HyperLink NavigateUri="http://www.site.com">
   Web Site
</HyperLink>

However, i've found this blog post with a custom TextBlock that is used as an HyperLink and supports click events.

Upvotes: 1

Related Questions