在WPF中使用超链接的示例
我见过几个build议,你可以通过Hyperlink
控制添加到WPF应用程序的Hyperlink
。
以下是我想要在代码中使用它的方法:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="BookmarkWizV2.InfoPanels.Windows.UrlProperties" Title="UrlProperties" Height="754" Width="576"> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition Height="40"/> </Grid.RowDefinitions> <Grid> <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.RowSpan="2"> <StackPanel > <DockPanel LastChildFill="True" Margin="0,5"> <TextBlock Text="Url:" Margin="5" DockPanel.Dock="Left" VerticalAlignment="Center"/> <TextBox Width="Auto"> <Hyperlink NavigateUri="http://www.google.co.in"> Click here </Hyperlink> </TextBox> </DockPanel > </StackPanel> </ScrollViewer> </Grid> <StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Margin="0,7,2,7" Grid.Row="1" > <Button Margin="0,0,10,0"> <TextBlock Text="Accept" Margin="15,3" /> </Button> <Button Margin="0,0,10,0"> <TextBlock Text="Cancel" Margin="15,3" /> </Button> </StackPanel> </Grid> </Window>
我得到以下错误:
属性“文本”不支持“超链接”types的值。
我究竟做错了什么?
如果您希望应用程序在Web浏览器中打开链接,则需要添加一个HyperLink ,将RequestNavigate事件设置为一个函数,该函数以编程方式打开一个Web地址浏览器,并将地址作为参数。
<TextBlock> <Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate"> Click here </Hyperlink> </TextBlock>
在代码隐藏中,您需要添加类似于此的内容来处理RequestNavigate事件。
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); e.Handled = true; }
另外你还需要下面的导入。
using System.Diagnostics; using System.Windows.Navigation;
在你的应用程序中看起来像这样。
除了富士的回应之外,我们还可以让处理程序可重用,把它变成一个附属的属性:
public static class HyperlinkExtensions { public static bool GetIsExternal(DependencyObject obj) { return (bool)obj.GetValue(IsExternalProperty); } public static void SetIsExternal(DependencyObject obj, bool value) { obj.SetValue(IsExternalProperty, value); } public static readonly DependencyProperty IsExternalProperty = DependencyProperty.RegisterAttached("IsExternal", typeof(bool), typeof(HyperlinkExtensions), new UIPropertyMetadata(false, OnIsExternalChanged)); private static void OnIsExternalChanged(object sender, DependencyPropertyChangedEventArgs args) { var hyperlink = sender as Hyperlink; if ((bool)args.NewValue) hyperlink.RequestNavigate += Hyperlink_RequestNavigate; else hyperlink.RequestNavigate -= Hyperlink_RequestNavigate; } private static void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); e.Handled = true; } }
像这样使用它:
<TextBlock> <Hyperlink NavigateUri="http://stackoverflow.com" custom::HyperlinkExtensions.IsExternal="true"> Click here </Hyperlink> </TextBlock>
Hyperlink
不是一个控件,它是一个stream内容元素,您只能在支持stream内容的控件中使用它,如TextBlock
。 文本TextBoxes
只有纯文本。
如果你想稍后本地化string,那么这些答案是不够的,我会build议像这样的东西:
<TextBlock> <Hyperlink NavigateUri="http://labsii.com/"> <Hyperlink.Inlines> <Run Text="Click here"/> </Hyperlink.Inlines> </Hyperlink> </TextBlock>
恕我直言,最简单的方法是使用从Hyperlink
inheritance的新控件:
/// <summary> /// Opens <see cref="Hyperlink.NavigateUri"/> in a default system browser /// </summary> public class ExternalBrowserHyperlink : Hyperlink { public ExternalBrowserHyperlink() { RequestNavigate += OnRequestNavigate; } private void OnRequestNavigate(object sender, RequestNavigateEventArgs e) { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); e.Handled = true; } }
我喜欢亚瑟的可重用处理程序的想法,但我认为有一个更简单的方法来做到这一点:
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) { if (sender.GetType() != typeof (Hyperlink)) return; string link = ((Hyperlink) sender).NavigateUri.ToString(); Process.Start(link); }
很明显,启动任何一种stream程都可能存在安全风险,所以要谨慎。
还要注意, Hyperlink
不必用于导航。 你可以把它连接到一个命令。
例如:
<TextBlock> <Hyperlink Command="{Binding ClearCommand}">Clear</Hyperlink> </TextBlock>
希望这可以帮助别人。
using System.Diagnostics; using System.Windows.Documents; namespace Helpers.Controls { public class HyperlinkEx : Hyperlink { protected override void OnClick() { base.OnClick(); Process p = new Process() { StartInfo = new ProcessStartInfo() { FileName = this.NavigateUri.AbsoluteUri } }; p.Start(); } } }