如何在XAML中创建一个简单的超链接?

61

我想在XAML中创建一个小超链接,但是尝试了各种方法均未成功。现在我放弃了。

请问如何编写语法?

<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团队:在Visual Studio 2010中,我希望Clippy弹出并说:“看起来您正在尝试创建超链接”,然后告诉我如何做到这一点。你们不能用MEF做到这一点吗?这将是复古的酷炫效果,而且这些小问题“我该如何在HTML中做我已经知道如何做的事情”会在学习XAML的过程中浪费很多时间。


8
“我已经知道如何在HTML中完成某项任务,但我不知道如何在XAML中完成。这种问题会在学习XAML的过程中耗费很多时间。” - “兄弟,你说得没错。” - Adrian K
2
尊敬的,将Clippy放入VS是一个非常糟糕的想法!你能想象那个讨厌的纸夹会捡起你正在编程的内容并提出无效的建议吗?我认为在开始之前学习WPF可以避免这些问题。 - MikeKulls
2
在编写XAML时,我经常感叹“如果这是CSS就好了...” - Shawn J. Molloy
8个回答

174
你不能将超链接添加到StackPanel中,否则会出现运行时错误。 (实际上,我有点惊讶它不是编译时错误。)这是因为Hyperlink不属于WPF的“控件”一侧,如

38

您可以使用自定义控件模板创建一个按钮,下面的代码是一个简单的超链接样式按钮(例如,它仅支持文本超链接),但可能会指导您朝正确的方向发展。

<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>

35

试一下这个:

<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);
}

1
工作正常,一个建议是,如果超链接被称为 btnHyperlink,则可以修改事件处理程序:private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) { System.Diagnostics.Process.Start(btnHyperlink.NavigateUri.AbsoluteUri); } - Sudhanshu Mishra
2
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri) 是什么意思? - Ahmad

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

这将使嵌套文本块中绑定的任何文本链接化,我尚未找到更好的方法,如果可能的话,我希望第一个文本块不存在。这也适用于数据模板。


4

如果您绑定的不是简单文本值,您可能会发现需要使用ContentPresenter,否则将不会显示任何内容。如果您绑定到XML数据源,则可能是这样。

IsMouseOver属性触发器会给文本添加下划线。

下面是一个绑定到XML的示例。

<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>

2

您可以使用HyperlinkButton来实现。当用户点击时,URL 将在您的网络浏览器中显示:

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

在通用 Windows 应用程序的 XAML 中,TargetName 是无效的。请仅使用 NavigateUri 和 Content。 - yehanny

1
通常,超链接的含义是为用户提供一个锚点,将其发送到另一页或一般来说是另一个资源,因此它是以这样的方式实现的,您必须指定该资源的位置,如下所示:
<HyperLink NavigateUri="http://www.site.com">
   Web Site
</HyperLink>

然而,我发现了这篇博客文章,其中使用自定义TextBlock作为超链接并支持点击事件。


1
这应该是超链接,而不是HyperLink。 - dmo
不需要这样做。只需从超链接中获取RequestNavigate事件即可。 - MikeKulls

0

在使用mvvmcross的UWP中,我正在使用这个

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接