Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
667 views
in Technique[技术] by (71.8m points)

c# - Create Hyperlink in TextBlock via Binding

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

 <TextBlock Tag="{Binding message}" x:Name="postDescription" TextWrapping="Wrap" 
  Grid.Row="3" Grid.ColumnSpan="3" Margin="10,10,10,12" FontSize="16" 
  TextAlignment="Justify" Foreground="{StaticResource foreGroundWhite}" >
    <Run Text="{Binding description, Converter={StaticResource statusFormatter}}" />
  </TextBlock>

In code,

public class StatusFormatter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            return returnTextWithUrl((String)value);
        }

        public static String returnTextWithUrl(String text)
        {
            if(text == null) { return null;  }
            MatchCollection mactches = uriFindRegex.Matches(text);

            foreach (Match match in mactches)
            {
                //Need Help here
                HyperlinkButton hyperlink = new HyperlinkButton();
                hyperlink.Content = match.Value;
                hyperlink.NavigateUri = new Uri(match.Value);
                text = text.Replace(match.Value, ??);
            }
            return text;
        }
}
}

The output should be something like this

<TextBlock Tag="{Binding message}" x:Name="postDescription" TextWrapping="Wrap" 
      Grid.Row="3" Grid.ColumnSpan="3" Margin="10,10,10,12" FontSize="16" 
      TextAlignment="Justify" Foreground="{StaticResource foreGroundWhite}" >
        Click this link -
        <Hyperlink NavigateUri="http://www.bing.com">bing</Hyperlink>
        - for more info.
      </TextBlock>

Any Help?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...