在.NET 4.7中的一个简单Windows窗体应用程序中,我的窗体上只有一个RichTextBox
。我正在从本地加载一个在MS Word 2016中创建的 *.rtf文件。超链接已在Word中设置。问题是,当单击应用程序中的超链接时,并非所有链接都触发LinkClicked
事件。
**行为如下:**如果超链接后面有足够多的字符(视情况而定),它将由LinkClicked事件触发。如果删除超链接后面的字符,它将不会触发该事件。
在做了一些测试之后,需要在最后一个URL之后插入的字符数等于正在加载的 *.rtf文件中所有URL的字符总数。
- 我无法上传图片,括号中的文字是超链接 *
不工作:[单击此处]了解更多信息。
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang4105{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Riched20 10.0.17134}\viewkind4\uc1
{\field{\*\fldinst { HYPERLINK "http://www.google.com" }}{\fldrslt {Click here}}}
\pard\sa200\sl276\slmult1\f0\fs22\lang9 for more information.\par
}
Works:[点击这里]了解更多信息。Lorem ipsum
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang4105{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Riched20 10.0.17134}\viewkind4\uc1
{\field{\*\fldinst { HYPERLINK "http://www.google.com" }}{\fldrslt {Click here}}}
\pard\sa200\sl276\slmult1\f0\fs22\lang9 for more information. Lorem ipsum\par
}
链接工作所需的字符数在大约20到大约100个字符之间变化。
我创建了一个小项目,以确保该问题不是源于主项目中的其他任何地方。该项目只包含一个RichTextBox
。我将DetectUrls
设置为True,这没有任何区别。我还尝试在Google Docs中创建 *.rtf文件,以检查是否是Word的版本问题。我还使用写字板进行了测试。在Notepad++中手动添加URL。在.NET Framework 4.6中不会出现此问题,但我要求使用.NET 4.7。如果我动态添加链接,也不会出现此问题,但我无法根据要求进行此操作。
Public Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
Dim LoadFileName As Object
LoadFileName = "C:\Users\anononym\source\repos\WindowsApp1\Test.rtf"
RichTextBox1.LoadFile(LoadFileName, RichTextBoxStreamType.RichText)
End Sub
Private Sub RichTextBox_LinkClicked(sender As Object, e As LinkClickedEventArgs) Handles RichTextBox1.LinkClicked
System.Diagnostics.Process.Start(e.LinkText)
End Sub
预期的结果是超链接重定向到在Word中设置的网站在所有情况下,我使用www.google.com进行测试。
2条答案
按热度按时间kq0g1dla1#
从.NET 4.7开始,
RichTextBox
使用RichEdit 50控件;以前的版本使用的是RichEdit 20控件。2我不知道两个控件版本在处理超链接时有什么不同,但很明显是有一些不同的。一种解决方法是将.NET 4.7应用程序配置为使用较旧的控件。这可以通过将以下内容添加到
App.config
文件中来完成。问题的根源似乎是原始
RichTextBox.CharRangeToString
方法中的一个黑客。使用RichEdit 50控件中可用的Friendly Name Hyperlinks时,
RichTextBox.Text.Length
属性可以小于c.cpMax
值,因为链接未包含在传回的属性值中。这会导致方法将String.Empty
传回呼叫的RichTextBox.EnLinkMsgHandler
方法,而呼叫的RichTextBox.EnLinkMsgHandler
方法在传回Empty.String
时不会引发LickClicked事件。为了处理这个 bug,下面定义了一个定制的
RichTextBox
类来修改CharRangeToString
方法的逻辑。这个修改的逻辑在WndProc
过程中被调用来绕过默认逻辑。虽然上面的代码不是很重要,但它需要几个来自基础实现的方法/结构,这些方法/结构是不可公开访问的。下面给出了这些方法的VB版本。大多数是从原始C#源代码直接转换而来的。
将这些类添加到我们的项目中并执行一个生成。
RichTextBoxFixedForFriendlyLinks
应该在工具箱中可用。您可以在通常使用RichTextBox
控件的地方使用它。此问题已在MS开发人员社区上发布为:WinForm RichTextBox LinkClicked event fails to fire when control loaded with RTF containing a friendly name hyperlink
rm5edbpk2#
这是一个@TnTinMn的VB实现的C#转换,它对我很有效。感谢https://github.com/icsharpcode/CodeConverter完成了大部分的转换。
显然,根据需要更改下面的命名空间。再次感谢,@TnTinMn。
RichTextBoxFixedForFriendlyLinks.cs
NativeMthods.cs: