Ich habe mehrere Vorschläge gesehen, die Sie über die Hyperlink
-Steuerung der WPF-Anwendung einen Hyperlink hinzufügen können.
So versuche ich es in meinem Code zu verwenden:
<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>
Ich erhalte folgenden Fehler:
Die Eigenschaft 'Text' unterstützt keine Werte vom Typ 'Hyperlink'.
Was mache ich falsch?
Wenn Sie möchten, dass Ihre Anwendung den Link in einem Webbrowser öffnet, müssen Sie einen HyperLink mit dem Ereignis RequestNavigate auf eine Funktion setzen, die einen Webbrowser mit der Adresse programmgesteuert öffnet ein Parameter.
<TextBlock>
<Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate">
Click here
</Hyperlink>
</TextBlock>
Im Code-behind müssen Sie etwas Ähnliches hinzufügen, um das RequestNavigate-Ereignis zu verarbeiten.
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
Zusätzlich benötigen Sie noch folgende Importe.
using System.Diagnostics;
using System.Windows.Navigation;
Das würde in Ihrer Bewerbung so aussehen.
Zusätzlich zu Fujis Antwort können wir den Handler wiederverwendbar machen, um ihn in eine angehängte Eigenschaft zu verwandeln:
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;
}
}
Und benutze es so:
<TextBlock>
<Hyperlink NavigateUri="http://stackoverflow.com" custom::HyperlinkExtensions.IsExternal="true">
Click here
</Hyperlink>
</TextBlock>
Hyperlink
ist nicht ein Steuerelement, es ist ein flow content -Element. Sie können es nur in Steuerelementen verwenden, die Fließinhalte unterstützen, wie eine TextBlock
. TextBoxes
hat nur Klartext.
Wenn Sie den String später lokalisieren möchten, reichen diese Antworten nicht aus. Ich würde Folgendes vorschlagen:
<TextBlock>
<Hyperlink NavigateUri="http://labsii.com/">
<Hyperlink.Inlines>
<Run Text="Click here"/>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
IMHO ist die einfachste Methode die Verwendung eines neuen Steuerelements, das von Hyperlink
geerbt wurde:
/// <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;
}
}
Beachten Sie auch, dass Hyperlink
nicht für die Navigation verwendet werden muss. Sie können es mit einem Befehl verbinden.
Zum Beispiel:
<TextBlock>
<Hyperlink Command="{Binding ClearCommand}">Clear</Hyperlink>
</TextBlock>
Ich mochte Arthurs Idee eines wiederverwendbaren Handlers, aber es gibt einen einfacheren Weg, dies zu tun:
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
if (sender.GetType() != typeof (Hyperlink))
return;
string link = ((Hyperlink) sender).NavigateUri.ToString();
Process.Start(link);
}
Natürlich kann es zu Sicherheitsrisiken kommen, wenn ein Prozess gestartet wird, also seien Sie vorsichtig.
Hoffe, das hilft auch jemandem.
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();
}
}
}
Eine der schönsten Möglichkeiten meiner Meinung nach (da sie jetzt allgemein verfügbar ist) ist das Verwenden von Verhalten.
Es benötigt:
Microsoft.Xaml.Behaviors.Wpf
xAML-Code:
xmlns:Interactions="http://schemas.Microsoft.com/xaml/behaviors"
UND
<Hyperlink NavigateUri="{Binding Path=Link}">
<Interactions:Interaction.Behaviors>
<behaviours:HyperlinkOpenBehaviour ConfirmNavigation="True"/>
</Interactions:Interaction.Behaviors>
<Hyperlink.Inlines>
<Run Text="{Binding Path=Link}"/>
</Hyperlink.Inlines>
</Hyperlink>
verhaltenscode:
using System.Windows;
using System.Windows.Documents;
using System.Windows.Navigation;
using Microsoft.Xaml.Behaviors;
namespace YourNameSpace
{
public class HyperlinkOpenBehaviour : Behavior<Hyperlink>
{
public static readonly DependencyProperty ConfirmNavigationProperty = DependencyProperty.Register(
nameof(ConfirmNavigation), typeof(bool), typeof(HyperlinkOpenBehaviour), new PropertyMetadata(default(bool)));
public bool ConfirmNavigation
{
get { return (bool) GetValue(ConfirmNavigationProperty); }
set { SetValue(ConfirmNavigationProperty, value); }
}
/// <inheritdoc />
protected override void OnAttached()
{
this.AssociatedObject.RequestNavigate += NavigationRequested;
this.AssociatedObject.Unloaded += AssociatedObjectOnUnloaded;
base.OnAttached();
}
private void AssociatedObjectOnUnloaded(object sender, RoutedEventArgs e)
{
this.AssociatedObject.Unloaded -= AssociatedObjectOnUnloaded;
this.AssociatedObject.RequestNavigate -= NavigationRequested;
}
private void NavigationRequested(object sender, RequestNavigateEventArgs e)
{
if (!ConfirmNavigation || MessageBox.Show("Are you sure?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
OpenUrl();
}
e.Handled = true;
}
private void OpenUrl()
{
// Process.Start(new ProcessStartInfo(AssociatedObject.NavigateUri.AbsoluteUri));
MessageBox.Show($"Opening {AssociatedObject.NavigateUri}");
}
/// <inheritdoc />
protected override void OnDetaching()
{
this.AssociatedObject.RequestNavigate -= NavigationRequested;
base.OnDetaching();
}
}
}