WPF में हाइपरलिंक का उपयोग करके उदाहरण


160

मैंने कई सुझाव देखे हैं, कि आप Hyperlinkनियंत्रण के माध्यम से WPF एप्लिकेशन में हाइपरलिंक जोड़ सकते हैं ।

मैं इसे अपने कोड में उपयोग करने का प्रयास कर रहा हूं:

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

मुझे निम्न त्रुटि मिल रही है:

संपत्ति 'पाठ' प्रकार 'हाइपरलिंक' के मूल्यों का समर्थन नहीं करता है।

मैं क्या गलत कर रहा हूं?

जवाबों:


331

यदि आप एक में लिंक को खोलने के अपने आवेदन चाहते हैं वेब ब्राउज़र आप एक जोड़ने की जरूरत है हाइपरलिंक के साथ RequestNavigate एक समारोह है कि प्रोग्राम के रूप में एक पैरामीटर के रूप पते के साथ एक वेब ब्राउज़र को खोलता है करने के लिए घटना सेट।

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

यह आपके आवेदन में इस तरह दिखेगा।

ऊ


6
नोट: RequestNavigateEventArgsमें है System.Windows.Navigationनाम स्थान।
बेन

2
धन्यवाद, लेकिन क्या बंधन के माध्यम से लिंक-टेक्स्ट ("इस मामले में यहां क्लिक करें") को निर्दिष्ट करने का कोई तरीका है?
एजेंट 007 6

6
बस फिर से हाइपरलिंक के अंदर एक टेक्स्टब्लॉक डालें और टेक्स्टप्रॉपर्टी को बांधें
KroaX

2
नोट # 2: Processऔर नाम स्थान ProcessStartInfoमें दोनों हैं System.Diagnostics
user2023861

3
महत्वपूर्ण टिप्पणी : आपके पास एक गैर-खाली नवगीतयूरी या घटना होनी चाहिए RequestNavigate को कभी नहीं बुलाया जाता है
MuiBienCarlota

60

फ़ूजी की प्रतिक्रिया के अलावा, हम हैंडलर को पुन: प्रयोज्य बना सकते हैं, इसे संलग्न संपत्ति में बदल सकते हैं:

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>

सुरुचिपूर्ण समाधान। धन्यवाद
Jeson Martajaya


26

यदि आप बाद में स्ट्रिंग का स्थानीयकरण करना चाहते हैं, तो वे उत्तर पर्याप्त नहीं हैं, मैं कुछ सुझाव दूंगा:

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

21

IMHO का सबसे सरल तरीका है कि विरासत में प्राप्त नए नियंत्रण का उपयोग करें 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;
    }
}

16

ध्यान दें कि Hyperlinkनेविगेशन के लिए उपयोग करने की आवश्यकता नहीं है। आप इसे एक कमांड से जोड़ सकते हैं।

उदाहरण के लिए:

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

16

मैंने इस प्रश्न में उत्तर का उपयोग किया और मुझे इसके साथ मुद्दा मिला।

यह अपवाद लौटाता है: {"The system cannot find the file specified."}

थोड़ी छानबीन के बाद। यह पता चला है कि यदि आपका WPF एप्लिकेशन है। तो आपको क्या करना UseShellExecuteहै true

यह Microsoft डॉक्स में उल्लिखित है :

सच है अगर प्रक्रिया शुरू करते समय शेल का उपयोग किया जाना चाहिए; गलत है अगर प्रक्रिया सीधे निष्पादन योग्य फ़ाइल से बनाई जानी चाहिए। .NET फ्रेमवर्क ऐप्स पर डिफ़ॉल्ट सही है और .NET कोर ऐप्स पर गलत है।

तो इस काम को करने के लिए आपको इसमें जोड़ा UseShellExecuteजाना चाहिए true:

Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri){ UseShellExecute = true });

मेरे पास यही मुद्दा था और यहां आया था कि इसे कैसे ठीक किया जाए, लेकिन यह अभी भी UseShelExecute = trueकिसी भी विचार के साथ बना हुआ है क्यों?
हाई प्लेन्स ग्रिफ्टर

@HighPlainsGrifter तो बस समझने के लिए आपने UseShelExecute = सही बनाया है लेकिन अभी भी एक ही मुद्दा है? अगर ऐसा है तो अपने दृश्य स्टूडियो को व्यवस्थापक मोड में चलाएं (व्यवस्थापक के रूप में चलाएं) मुझे लगता है कि इस प्रक्रिया के लिए संसाधनों को एक्सेस करने की आवश्यकता है जो कि व्यवस्थापक विशेषाधिकार की आवश्यकता है। और यह सच्ची बात केवल .core परियोजनाओं के लिए मान्य है। अगर मुझे मदद मिलती है तो मुझे बताएं ताकि मैं अपना जवाब अपडेट कर सकूं।
मेथम

हां, मैं अपने व्यवस्थापक उपयोगकर्ता के रूप में चल रहा हूं Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });और "System.ComponentModel.Win32Exception" त्रुटि प्राप्त करें और : हाइपरलिंक का पालन करने का प्रयास करते समय "सिस्टम निर्दिष्ट फ़ाइल को नहीं ढूँढ सकता है"
हाई प्लेन्स ग्रिफ़र

@HighPlainsGrifter सुनिश्चित नहीं है कि यह क्या हो सकता है, अगर आपके पास स्रोत कोड है तो मैं इसे डिबग करने में कुछ समय बिताने के लिए तैयार हूं लेकिन किसी भी चीज का वादा नहीं करता। :)
मेथम-12

वास्तव में दुख की बात नहीं है कोड - मैं अभी परियोजना को पकड़ने के बजाय एक हाइपरलिंक का उपयोग नहीं करना पड़ा है। फिर भी धन्यवाद।
हाई प्लेन्स ग्रिफ़र

4

मुझे एक पुन: प्रयोज्य हैंडलर का आर्थर विचार पसंद आया, लेकिन मुझे लगता है कि इसे करने का एक सरल तरीका है:

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

जाहिर है कि किसी भी तरह की प्रक्रिया शुरू करने के साथ सुरक्षा जोखिम हो सकते हैं, इसलिए सावधानी रखें।


1

आशा है कि यह भी किसी की मदद करें।

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

0

मेरी राय में सबसे सुंदर तरीकों में से एक (क्योंकि यह अब उपलब्ध है) व्यवहार का उपयोग कर रहा है।

इसकी जरूरत है:

  • नगेट निर्भरता: Microsoft.Xaml.Behaviors.Wpf
  • यदि आपके पास पहले से निर्मित व्यवहार हैं, तो आपको माइक्रोसॉफ़्ट ब्लॉग पर इस गाइड का अनुसरण करना पड़ सकता है ।

xaml कोड:

xmlns:Interactions="http://schemas.microsoft.com/xaml/behaviors"

तथा

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

व्यवहार कोड:

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();
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.