Search code examples
c#jsonuwptextblock

Detect is a website address or email address on textblock


I have a TextBlock whose data comes from JSON. I would like if the textblock the website address or email, the text color becomes blue and the user can click (if the email address it will go to the email application and the user can write an email directly to this address. Meanwhile, if the website address, it will immediately open the web browser). XAML:

<TextBlock x:Name="DetailDeskripsi" Width="290" Text="{Binding Deskripsi}" VerticalAlignment="Top" HorizontalAlignment="Left" Height="auto" TextWrapping="Wrap" FontSize="15" TextAlignment="Justify" Foreground="#FFCA6402"/>

Example of JSON Data from http://.../mobileapp/GetPostByCategoryXMLa?term_id=378: JSON

How do I apply it?


Solution

  • I've modified a little the answer from here and now it processes the bound string, searching for website and e-mail adresses. Once it founds one, it creates a hyperlink which should fire e-mail app or webbrowser.

    The code for TextBlock extendion:

    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 && !string.IsNullOrWhiteSpace(text))
                {
                    textBl.Inlines.Clear();
                    Regex regx = new Regex(@"(http(s)?://[\S]+|www.[\S]+|[\S]+@[\S]+)", RegexOptions.IgnoreCase);
                    Regex isWWW = new Regex(@"(http[s]?://[\S]+|www.[\S]+)");
                    Regex isEmail = new Regex(@"[\S]+@[\S]+");
                    foreach (var item in regx.Split(text))
                    {
                        if (isWWW.IsMatch(item))
                        {
                            Hyperlink link = new Hyperlink { NavigateUri = new Uri(item.ToLower().StartsWith("http") ? item : $"http://{item}"), Foreground = Application.Current.Resources["SystemControlForegroundAccentBrush"] as SolidColorBrush };
                            link.Inlines.Add(new Run { Text = item });
                            textBl.Inlines.Add(link);
                        }
                        else if (isEmail.IsMatch(item))
                        {
                            Hyperlink link = new Hyperlink { NavigateUri = new Uri($"mailto:{item}"), Foreground = Application.Current.Resources["SystemControlForegroundAccentBrush"] as SolidColorBrush };
                            link.Inlines.Add(new Run { Text = item });
                            textBl.Inlines.Add(link);
                        }
                        else textBl.Inlines.Add(new Run { Text = item });
                    }
                }
            }));
    }
    

    And the code in xaml:

    <TextBlock extension:TextBlockExtension.FormattedText="{x:Bind TextToFormat, Mode=OneWay}" FontSize="15" Margin="10" TextWrapping="WrapWholeWords"/>
    

    The working sample you will find at my Github - I've tested it with your json and it looks/works quite nice:

    enter image description here