WPF 动态超链接 RichTextbox
WPF Dynamic HyperLinks RichTextbox
从 2006 年到现在,我看到过几篇关于如何向 RichTextBox 添加超链接的不同形式的帖子,但它们对于我想要的东西来说似乎都过于复杂。我正在创建一个桌面聊天客户端,我接收到字符串形式的输入,现在这些字符串中可能有一些 url,我需要这些 url 是可点击的。据我所知,这意味着它们需要是 HyperLink 对象。
在 RichTextBox 中导航并用超链接替换 url 似乎不是一件容易的事。有人对此有相对简单的解决方案吗?
在我的 Web 客户端中,它是一个简单的单行程序
value = value.replace(/(http:\/\/[^\s]+)/gi, '<a href="" target="_blank"></a>');
从没想过我会看到 C# 真正让它变得更难的那一天。
如果您想在 WPF 中执行与 value.replace(/(http:\/\/[^\s]+)/gi, '<a href="" target="_blank"></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;
}
}
它使用与您提供的相同的正则表达式,如果您想正确地使用正则表达式识别 URLs,则缺少它。这个不识别 https,下面句子中的最后一个点将是 URL 的一部分:"This is a URL: http://www.google.com/."
代码所做的是根据正则表达式拆分文本,对其进行迭代并将正确的元素添加到动态构建的 FlowDocument
中。
点击 Hyperlink
应该会打开您的默认浏览器。
结果:
也就是说,这仅适用于 RichTextBox
的只读用法(如评论中的问题所示)。
从 2006 年到现在,我看到过几篇关于如何向 RichTextBox 添加超链接的不同形式的帖子,但它们对于我想要的东西来说似乎都过于复杂。我正在创建一个桌面聊天客户端,我接收到字符串形式的输入,现在这些字符串中可能有一些 url,我需要这些 url 是可点击的。据我所知,这意味着它们需要是 HyperLink 对象。
在 RichTextBox 中导航并用超链接替换 url 似乎不是一件容易的事。有人对此有相对简单的解决方案吗?
在我的 Web 客户端中,它是一个简单的单行程序
value = value.replace(/(http:\/\/[^\s]+)/gi, '<a href="" target="_blank"></a>');
从没想过我会看到 C# 真正让它变得更难的那一天。
如果您想在 WPF 中执行与 value.replace(/(http:\/\/[^\s]+)/gi, '<a href="" target="_blank"></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;
}
}
它使用与您提供的相同的正则表达式,如果您想正确地使用正则表达式识别 URLs,则缺少它。这个不识别 https,下面句子中的最后一个点将是 URL 的一部分:"This is a URL: http://www.google.com/."
代码所做的是根据正则表达式拆分文本,对其进行迭代并将正确的元素添加到动态构建的 FlowDocument
中。
点击 Hyperlink
应该会打开您的默认浏览器。
结果:
也就是说,这仅适用于 RichTextBox
的只读用法(如评论中的问题所示)。