WPF动态HyperLinks RichTextbox

时间:2016-01-15 18:41:42

标签: wpf dynamic hyperlink richtextbox

从2006年到现在,我已经看到了各种各种形式的帖子,关于如何向RichTextBox添加超链接,但它们对于我想要的东西看起来都过于复杂。我正在创建一个桌面聊天客户端,我接收输入为字符串,现在这些字符串可能是一些网址,我需要这些网址是可点击的。从我收集到的内容意味着他们需要成为HyperLink对象。

浏览RichTextBox并用HyperLinks替换网址似乎不小。有人有一个相对简单的解决方案吗?

在我的网络客户端中,它是一个简单的一行

value = value.replace(/(http:\/\/[^\s]+)/gi, '<a href="$1" target="_blank">$1</a>');

从未想过我会看到C#实际上变得更难的那一天。

1 个答案:

答案 0 :(得分:0)

如果您想在WPF中执行等效的value.replace(/(http:\/\/[^\s]+)/gi, '<a href="$1" target="_blank">$1</a>')

<RichTextBox x:Name="MyRichTextBox" IsDocumentEnabled="True" IsReadOnly="True" />

转换字符串的代码如下:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var htmlText = "Google's website is http://www.google.com";
        MyRichTextBox.Document = ConvertToFlowDocument(htmlText);
    }

    private FlowDocument ConvertToFlowDocument(string text)
    {
        var flowDocument = new FlowDocument();

        var regex = new Regex(@"(http:\/\/[^\s]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        var matches = regex.Matches(text).Cast<Match>().Select(m => m.Value).ToList();

        var paragraph = new Paragraph();
        flowDocument.Blocks.Add(paragraph);

        foreach (var segment in regex.Split(text))
        {
            if (matches.Contains(segment))
            {
                var hyperlink = new Hyperlink(new Run(segment))
                {
                    NavigateUri = new Uri(segment),
                };
                hyperlink.RequestNavigate += (sender, args) => Process.Start(segment);

                paragraph.Inlines.Add(hyperlink);
            }
            else
            {
                paragraph.Inlines.Add(new Run(segment));
            }
        }

        return flowDocument;
    }
}

它使用您提供的相同正则表达式,如果您正确地想要使用正则表达式识别URL,则缺少该正则表达式。这个不识别https,下一句中的最后一个点将成为URL的一部分:"This is a URL: http://www.google.com/."

代码的作用是根据正则表达式拆分文本,迭代它并将正确的元素添加到动态构造的FlowDocument中。

点击Hyperlink应该会打开默认浏览器。

结果:

Result

那就是说,这只适用于RichTextBox的只读用法(如评论中的问题所示)。