2012-04-20 20 views
112

Ho visto diversi suggerimenti, che è possibile aggiungere il collegamento ipertestuale all'applicazione WPF tramite il controllo Hyperlink.Esempio di utilizzo del collegamento ipertestuale in WPF

ecco come sto cercando di usarla nel mio codice:

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

sto ottenendo seguente errore:

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

Che cosa sto facendo di sbagliato?

risposta

246

Se si desidera che l'applicazione per aprire il collegamento in una web browser è necessario aggiungere un HyperLink con l'evento RequestNavigate impostato su una funzione che si apre a livello di codice un browser web con l'indirizzo come parametro.

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

Nel code-behind si avrebbe bisogno di aggiungere qualcosa di simile a questo per gestire l'evento RequestNavigate.

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

Inoltre, sono necessarie anche le seguenti importazioni.

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

Sarebbe come questo nella vostra applicazione.

oO

+4

Nota: 'RequestNavigateEventArgs' è nel System.Windows.Navigation' namespace'. – Ben

+2

Grazie, ma esiste un modo per specificare il testo del collegamento ("Clicca qui" in questo caso) tramite associazione? – Agent007

+5

Basta mettere un blocco di testo all'interno del collegamento ipertestuale di nuovo e vincolare la Textproperty – KroaX

24

Hyperlink è non un controllo, si tratta di un elemento flow content, è possibile utilizzare solo nei controlli che supportano i contenuti del flusso, come un TextBlock. TextBoxes hanno solo testo semplice.

51

Oltre alla risposta di Fuji, possiamo fare il gestore riutilizzabile trasformandolo in una proprietà associata:

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

e usarlo in questo modo:

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

mi è piaciuto L'idea di Arthur di un gestore riutilizzabile, ma penso che ci sia un modo più semplice per farlo:

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

Ovviamente ci potrebbero essere dei rischi per la sicurezza con l'avvio di qualsiasi tipo di processo, quindi state attenti.

7

IMHO il modo più semplice è quello di utilizzare nuovo controllo ereditato da 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

Se si vuole localizzare stringa tardi, allora quelle risposte non sono abbastanza, vorrei suggerire qualcosa di simile:

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

Spero che questo aiuti anche qualcuno.

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

Nota anche che Hyperlink non deve essere utilizzato per la navigazione. Puoi collegarlo a un comando.

Ad esempio:

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