0

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?

Rose
  • 613
  • 4
  • 22
  • Stanislav Kniazev's answer should help. http://stackoverflow.com/questions/2092890/add-hyperlink-to-textblock-wpf – HebeleHododo Nov 25 '16 at 08:19
  • it not wpf, but on uwp – Rose Nov 25 '16 at 08:30
  • What is under property *Deskripsi*? I think you can take a look at [this answer](http://stackoverflow.com/a/27742886/2681948). – Romasz Nov 25 '16 at 08:52
  • Deskripsi is taken from the JSON object post_clean So textblock description will retrieve data from the JSON object post_clean. If the inside there is a link or an email address, then the text color will change to 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) – Rose Nov 25 '16 at 09:39
  • @Rose UWP TextBlock has the Inlines property. Wouldn't the code in the edited part of the answer work? – HebeleHododo Nov 25 '16 at 10:09

1 Answers1

1

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

Community
  • 1
  • 1
Romasz
  • 29,662
  • 13
  • 79
  • 154
  • Data for JSON is not only one, but was taken from the link http://..../mobileapp/GetPostByCategoryXMLa?term_id=372 Users select items on gridview, then the item is displayed title, image, and description on page2. – Rose Nov 28 '16 at 09:51
  • @Rose I thought your question was about detecting email/website address. – Romasz Nov 29 '16 at 01:09
  • yes, my question was about detecting email/website address. Textblock is the data bindings that come from JSON data with links http://..../mobileapp/GetPostByCategoryXMLa?term_id=372 and the data for JSON not only one. I've tried to apply the code above, but does not detect them. On the first page there is a gridview which can be selected by the user. Once the user selects, will display a description which is textblock on page2 – Rose Nov 29 '16 at 01:28
  • Have you tried the sample above? If you bind a text - does it show it properly? – Romasz Nov 29 '16 at 07:32
  • I've tried, but could not be detected. Persists \r \n and the website address and email address undetected – Rose Nov 29 '16 at 07:38
  • i've tried it. But in the github sample the json is a file. But i need JSON on Url Link – Rose Nov 29 '16 at 07:51
  • It doesn't matter, you should pass a string to TextBlock, then it will work. – Romasz Nov 29 '16 at 07:55
  • Here is the project: drive.google.com/file/d/0B4oRSWSS0hKDNnJLclVTb3hhWlU/… Can you fix it? Note: for textblock for detect website and email address at Detail Page – Rose Nov 29 '16 at 08:43
  • Can anyone help me to fix my project? – Rose Dec 01 '16 at 01:58
  • Here is the project: http://drive.google.com/file/d/0B4oRSWSS0hKDNnJLclVTb3hhWlU/… Can you fix it? Note: for textblock for detect website and email address at Detail Page – Rose Dec 01 '16 at 01:58