2012-04-20 23 views
112

He visto varias sugerencias, que puede agregar un hipervínculo a la aplicación WPF a través del control Hyperlink.Ejemplo de uso de hipervínculo en WPF

Así es como estoy tratando de usarlo en mi código:

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

Estoy consiguiendo error siguiente:

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

¿Qué estoy haciendo mal?

Respuesta

246

Si desea que la aplicación para abrir el enlace en una web browser es necesario agregar un HyperLink con el evento RequestNavigate fijar a una función que se abre mediante programación un navegador web con la dirección como parámetro.

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

En el código subyacente que se necesita añadir algo similar a esto para controlar el evento RequestNavigate.

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

Además, también necesitará las siguientes importaciones.

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

Se vería así en su aplicación.

oO

+4

Nota: 'RequestNavigateEventArgs' está en el espacio de nombres' System.Windows.Navigation'. – Ben

+2

Gracias, pero ¿hay alguna forma de especificar el texto de enlace ("Haga clic aquí" en este caso) a través del enlace? – Agent007

+5

Simplemente coloque un Textblock dentro del hipervínculo nuevamente y enlace la propiedad de texto – KroaX

24

Hyperlink es no un control, que es un elemento flow content, sólo se puede utilizar en los controles que apoyan el contenido dinámico, como un TextBlock. TextBoxes solo tienen texto sin formato.

51

Además de la respuesta de Fuji, podemos hacer que el controlador reutilizable convirtiéndola en una propiedad asociada:

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

Y utilizar de esta manera:

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

me ha gustado La idea de Arthur de un manipulador reutilizable, pero creo que hay una manera más simple de hacerlo:

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

Obviamente, podría haber riesgos de seguridad al iniciar cualquier tipo de proceso, así que tenga cuidado.

7

mi humilde opinión, la forma más sencilla es utilizar nuevo control heredado 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 desea localizar cadena más tarde, entonces esas respuestas no son suficientes, sugeriría algo así como:

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

Espero que esto ayude a alguien también.

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

Tenga en cuenta también que Hyperlink no tiene que ser utilizado para la navegación. Puedes conectarlo a un comando.

Por ejemplo:

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