Bind text with links to RichTextBox

后端 未结 3 868
野趣味
野趣味 2020-12-06 03:16

I need to bind text which may contain hyperlinks to RichTextBox so it could show text as normal text and links as hyperlinks.

For example I have following text:

相关标签:
3条回答
  • 2020-12-06 03:51

    Thanks for the solution!

    One minor modification I made was right at the end, I replaced the check on the count, with a line that just adds a substring of the full text, this way it does not truncate everything after the last URL, all text is retained.

            paragraph.Inlines.Add(text.Substring(textPosition, text.Length - textPosition));
    
            //if (urlMatches.Count == 0)
            //{
            //    paragraph.Inlines.Add(text);
            //}
    
    0 讨论(0)
  • 2020-12-06 03:53

    Parse the Hyperlink, and create following structure (With C#, of course):

    <RichTextBlock>
        <Run>Hello World!</Run>
        <Hyperlink NavigateUri="http://www.stackoverflow.com">http://www.stackoverflow.com</Hyperlink>
    
    0 讨论(0)
  • 2020-12-06 03:58

    I implemented what I need

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Text.RegularExpressions;
    using System.Windows.Media;
    
    namespace NazarGrynko.UI.Controls
    {
        public class MyRichTextBox : RichTextBox
        {
            private const string UrlPattern = @"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?";
            public static readonly DependencyProperty TextProperty =
                DependencyProperty.Register("Text", typeof (string), typeof(MyRichTextBox ), new PropertyMetadata(default(string), TextPropertyChanged));
    
            public string Text
            {
                get { return (string) GetValue(TextProperty); }
                set { SetValue(TextProperty, value); }
            }
    
            private static void TextPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
            {
                var richTextBox = (MyRichTextBox)dependencyObject;
                var text = (string) dependencyPropertyChangedEventArgs.NewValue;
                int textPosition = 0;
                var paragraph = new Paragraph();
    
                var urlMatches = Regex.Matches(text, UrlPattern);
                foreach (Match urlMatch in urlMatches)
                {
                    int urlOccurrenceIndex = text.IndexOf(urlMatch.Value, textPosition, StringComparison.Ordinal);
    
                    if (urlOccurrenceIndex == 0)
                    {
                        var hyperlink = new Hyperlink
                                            {
                                                NavigateUri = new Uri(urlMatch.Value),
                                                TargetName = "_blank",
                                                Foreground = Application.Current.Resources["PhoneAccentBrush"] as Brush
                                            };
                        hyperlink.Inlines.Add(urlMatch.Value);
                        paragraph.Inlines.Add(hyperlink);
                        textPosition += urlMatch.Value.Length;
                    }
                    else
                    {
                        paragraph.Inlines.Add(text.Substring(textPosition, urlOccurrenceIndex - textPosition));
                        textPosition += urlOccurrenceIndex - textPosition;
                        var hyperlink = new Hyperlink
                                            {
                                                NavigateUri = new Uri(urlMatch.Value),
                                                TargetName = "_blank",
                                                Foreground = Application.Current.Resources["PhoneAccentBrush"] as Brush
                                            };
                        hyperlink.Inlines.Add(urlMatch.Value);
                        paragraph.Inlines.Add(hyperlink);
                        textPosition += urlMatch.Value.Length;
                    }
                }
    
                if (urlMatches.Count == 0)
                {
                    paragraph.Inlines.Add(text);
                }
    
                richTextBox.Blocks.Add(paragraph);
            }
        }
    }
    

    Using example:

    <MyRichTextBox Text="{Binding Message}"/>
    
    0 讨论(0)
提交回复
热议问题