6

ハイパーリンクを含む可能性のあるテキストを RichTextBox にバインドして、テキストを通常のテキストとして表示し、リンクをハイパーリンクとして表示できるようにする必要があります。

たとえば、次のテキストがあります。

Join us on social networks
http://www.facebook.com/

テキスト内のリンクをハイパーリンクにしたいので、RichTextBox の結果は次のようになります。

ソーシャルネットワークに参加してください

http://www.facebook.com/

4

3 に答える 3

11

必要なものを実装しました

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\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?";
        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);
        }
    }
}

使用例:

<MyRichTextBox Text="{Binding Message}"/>
于 2012-10-18T18:46:30.067 に答える
1

ハイパーリンクを解析し、次の構造を作成します(もちろん、C#を使用)。

<RichTextBlock>
    <Run>Hello World!</Run>
    <Hyperlink NavigateUri="http://www.stackoverflow.com">http://www.stackoverflow.com</Hyperlink>
于 2012-10-18T16:36:17.413 に答える
0

解決策をありがとう!

私が行った小さな変更の 1 つは、最後にありました。カウントのチェックを、全文の部分文字列を追加するだけの行に置き換えました。このようにして、最後の URL の後のすべてが切り捨てられず、すべてのテキストが保持されます。

        paragraph.Inlines.Add(text.Substring(textPosition, text.Length - textPosition));

        //if (urlMatches.Count == 0)
        //{
        //    paragraph.Inlines.Add(text);
        //}
于 2014-04-30T03:01:31.843 に答える