Create Hyperlink in TextBlock via Binding

前端 未结 3 531
死守一世寂寞
死守一世寂寞 2020-12-19 09:40

My problem is to find the urls from the text content and convert it into the clickable hyperlinks via data binding.

This is what I\'ve tried

 

        
相关标签:
3条回答
  • 2020-12-19 09:46

    To do what you want you will have to use Inlines property of your TextBlock, but as it's not a DependencyProperty, it cannot be a target of binding. We will have to extend your TextBlock class, but as it's sealed we will have to use other class.

    Lets define static class, which will add apropriate Inline - Hyperlink or Run, depending on Regex match. It can look for example like this:

    public static class TextBlockExtension
    {
        public static string GetFormattedText(DependencyObject obj)
        { return (string)obj.GetValue(FormattedTextProperty); }
    
        public static void SetFormattedText(DependencyObject obj, string value)
        { obj.SetValue(FormattedTextProperty, value); }
    
        public static readonly DependencyProperty FormattedTextProperty =
            DependencyProperty.Register("FormattedText", typeof(string), typeof(TextBlockExtension),
            new PropertyMetadata(string.Empty, (sender, e) =>
            {
                string text = e.NewValue as string;
                var textBl = sender as TextBlock;
                if (textBl != null)
                {
                    textBl.Inlines.Clear();
                    Regex regx = new Regex(@"(http://[^\s]+)", RegexOptions.IgnoreCase);
                    var str = regx.Split(text);
                    for (int i = 0; i < str.Length; i++)
                        if (i % 2 == 0)
                            textBl.Inlines.Add(new Run { Text = str[i] });
                        else
                        {
                            Hyperlink link = new Hyperlink { NavigateUri = new Uri(str[i]), Foreground = Application.Current.Resources["PhoneAccentBrush"] as SolidColorBrush };
                            link.Inlines.Add(new Run { Text = str[i] });
                            textBl.Inlines.Add(link);
                        }                        
                }
            }));
    }
    

    Then in XAML we use it just like this:

    <TextBlock local:TextBlockExtension.FormattedText="{Binding MyText}" FontSize="15"/>
    

    And after putting some text to my property:

    private void firstBtn_Click(object sender, RoutedEventArgs e)
    {
        MyText = @"Simple text with http://mywebsite.com link";
    }
    

    I can see such a result:

    SampleLink

    0 讨论(0)
  • 2020-12-19 10:07

    I stumbled on this post while looking for the same for UWP. In case you are here too for the same, I'd recommend you use a HyperlinkButton instead of a Hyperlink wrapped in a Textblock. Below is the code on how to use it.

    <HyperlinkButton Content="{x:Bind Text}" NavigateUri="{x:Bind Hyperlink}"/>
    

    You can also use Binding instead of x:Bind and yes you can set the Mode=OneWay too.

    Read More on Microsoft Docs

    0 讨论(0)
  • 2020-12-19 10:08

    You can't put Hyperlink objects inside a String. Instead you need to return a Span containing inlines from your converter. The plain text will be Run objects and the links will be Hyperlink objects.

        public static Span returnTextWithUrl(String text)
        {
            if(text == null) { return null;  }
            var span = new Span();
            MatchCollection mactches = uriFindRegex.Matches(text);
            int lastIndex = 0;
            foreach (Match match in mactches)
            {
                var run = new Run(text.Substring(lastIndex, match.Index - lastIndex));
                span.Inlines.Add(run);
                lastIndex = match.Index + match.Length;
                var hyperlink = new Hyperlink();
                hyperlink.Content = match.Value;
                hyperlink.NavigateUri = new Uri(match.Value);
                span.Inlines.Add(hyperlink);
            }
            span.Inlines.Add(new Run(text.Substring(lastIndex)));
            return span;
        }
    
    0 讨论(0)
提交回复
热议问题