WPF动态超链接RichTextbox

WPF动态超链接RichTextbox,wpf,dynamic,hyperlink,richtextbox,Wpf,Dynamic,Hyperlink,Richtextbox,从2006年到现在,我已经看到过几篇关于如何向RichTextBox添加超链接的各种形式的帖子,但是对于我想要的内容来说,它们似乎都过于复杂了。我正在创建一个桌面聊天客户端,我以字符串的形式接收输入,现在这些字符串中可能有一些URL,我需要这些URL可以单击。从我收集的信息来看,这意味着它们必须是超链接对象 在RichTextBox中导航并用超链接替换URL似乎不是一件小事。有人有相对简单的解决方案吗 在我的web客户端中,它是一个简单的单行程序 value = value.replace(/(

从2006年到现在,我已经看到过几篇关于如何向RichTextBox添加超链接的各种形式的帖子,但是对于我想要的内容来说,它们似乎都过于复杂了。我正在创建一个桌面聊天客户端,我以字符串的形式接收输入,现在这些字符串中可能有一些URL,我需要这些URL可以单击。从我收集的信息来看,这意味着它们必须是超链接对象

在RichTextBox中导航并用超链接替换URL似乎不是一件小事。有人有相对简单的解决方案吗

在我的web客户端中,它是一个简单的单行程序

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

我从没想过有一天C会让它变得更难。

如果你想做一个等价的
值。在WPF中替换(/(http:\/\/[^\s]+)/gi,”)

<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;
    }
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
var htmlText=“谷歌的网站是http://www.google.com";
MyRichTextBox.Document=ConvertToFlowDocument(htmlText);
}
私有FlowDocument ConvertToFlowDocument(字符串文本)
{
var flowDocument=新的flowDocument();
var regex=new regex(@“(http:\/\/[^\s]+)”,RegexOptions.Compiled | RegexOptions.IgnoreCase);
var matches=regex.matches(text.Cast().Select(m=>m.Value.ToList();
var段落=新段落();
流程文件。块。添加(段落);
foreach(regex.Split中的var段(文本))
{
if(匹配.包含(段))
{
var hyperlink=新超链接(新运行(段))
{
NavigateUri=新Uri(段),
};
hyperlink.RequestNavigate+=(发送方,参数)=>Process.Start(段);
段落.内联线.添加(超链接);
}
其他的
{
段落.内联线.添加(新运行(段));
}
}
返回流程文件;
}
}
它使用与您提供的正则表达式相同的正则表达式,如果您希望正确地使用正则表达式识别URL,则缺少该正则表达式。这一个不识别https,下面句子中的最后一个点将是URL的一部分:
“这是一个URL:http://www.google.com/.“

代码所做的是基于正则表达式拆分文本,对其进行迭代,并将正确的元素添加到动态构建的
FlowDocument

单击超链接应打开默认浏览器

结果:


也就是说,这只适用于
RichTextBox
的只读使用(如注释中的问题所示)。

为了清楚起见,您关心的RichTextBox是否是用户输入的来源?或者您是否担心RichTextBox会显示完整对话的部分?还是两者都有?@Rowbear我最关心的是显示带有超链接的对话,让它们在输入richtextbox中可点击是一个额外的好处,但也必然是一个要求。我的web客户端有一个单独的正则表达式,可以使用https,基本上是一样的,但使用https而不是http。是的,这将是一个只读上下文,因为我只需要它点击一次收到不一定在发送。我会尝试一下,谢谢你的回复,我会让你知道事情的进展:)你的解决方案还差一点完美!我添加了一个参数来接受流文档,这样我就可以附加到RichTextBox中现有的流文档中。非常感谢,我是WPF的新手,绝对没有对流程文档做过任何事情。我加了一个s?如果有人在url末尾留下一个点,这是他们的错,那么它将识别https