2012-04-20 8 views
112

J'ai vu plusieurs suggestions, que vous pouvez ajouter un lien hypertexte à l'application WPF via le contrôle Hyperlink.Exemple utilisant un lien hypertexte dans WPF

Voici comment je suis en train de l'utiliser dans mon code:

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

Je reçois l'erreur suivante:

Property 'Text' does not support values of type 'Hyperlink'.

Qu'est-ce que je fais mal?

Répondre

246

Si vous souhaitez que votre application pour ouvrir le lien dans une web browser vous devez ajouter un HyperLink à l'événement RequestNavigate réglé sur une fonction qui ouvre un programme navigateur Web avec l'adresse en tant que paramètre.

<TextBlock>   
    <Hyperlink NavigateUri="http://www.google.com" RequestNavigate="Hyperlink_RequestNavigate"> 
     Click here 
    </Hyperlink> 
</TextBlock> 

Dans le code-behind vous devez ajouter quelque chose de semblable à cela pour gérer l'événement RequestNavigate.

private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) 
{ 
    Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); 
    e.Handled = true; 
} 

En outre, vous aurez également besoin des importations suivantes.

using System.Diagnostics; 
using System.Windows.Navigation; 

Cela ressemblerait à ceci dans votre application.

oO

+4

Note: 'RequestNavigateEventArgs' est dans l'espace de noms' System.Windows.Navigation'. – Ben

+2

Merci, mais est-il possible de spécifier le lien-texte ("Cliquez ici" dans ce cas) à travers la liaison? – Agent007

+5

Il suffit de mettre à nouveau un bloc de texte à l'intérieur du lien hypertexte et de lier la propriété de texte – KroaX

24

Hyperlink est pas un contrôle, il est un élément flow content, vous ne pouvez l'utiliser dans les contrôles qui prennent en charge le contenu de flux, comme un TextBlock. TextBoxes seulement avoir du texte brut.

51

En plus de la réponse de Fuji, nous pouvons faire le gestionnaire réutilisable en le transformant en une propriété attachée:

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

Et l'utiliser comme ceci:

<TextBlock> 
<Hyperlink NavigateUri="http://stackoverflow.com" custom::HyperlinkExtensions.IsExternal="true"> 
     Click here 
    </Hyperlink> 
</TextBlock> 
3

J'aimais L'idée d'Arthur d'un gestionnaire réutilisable, mais je pense qu'il y a une façon plus simple de le faire:

private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) 
{ 
    if (sender.GetType() != typeof (Hyperlink)) 
     return; 
    string link = ((Hyperlink) sender).NavigateUri.ToString(); 
    Process.Start(link); 
} 

Évidemment, il pourrait y avoir des risques de sécurité avec le démarrage de tout type de processus, alors soyez prudent.

7

à mon humble avis la plus simple est d'utiliser un nouveau contrôle hérité de Hyperlink:

/// <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; 
    } 
} 
14

Si vous souhaitez localiser chaîne plus tard, alors ces réponses ne suffisent pas, je dirais quelque chose comme:

<TextBlock> 
    <Hyperlink NavigateUri="http://labsii.com/"> 
     <Hyperlink.Inlines> 
      <Run Text="Click here"/> 
     </Hyperlink.Inlines> 
    </Hyperlink> 
</TextBlock> 
1

Espérons que cela aide quelqu'un aussi.

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

Notez également que Hyperlink ne doit pas nécessairement être utilisé pour la navigation. Vous pouvez le connecter à une commande.

Par exemple:

<TextBlock> 
    <Hyperlink Command="{Binding ClearCommand}">Clear</Hyperlink> 
</TextBlock> 
Questions connexes