RichTextBox控件中的损坏表(自动换行)

可能重复:
为什么richtextbox没有正确显示此表?

我们在Visual Studio 2008中遇到了Windows.Forms.RichTextBox控件的问题。

我们试图在Windows窗体应用程序(.NET 3.5)中显示由第三方作为RTF文件提供的文本。 在此RTF文本文件中有表,其中包含跨越多行的文本。 使用写字板或Word 2003打开时,RTF文件正确显示。

但是,当我们将RTF文件加载到RichTextBox控件中,或者将整个文本(包括表格)复制并粘贴到控件中时,表格无法正确显示 – 单元格只是单行,没有换行。

以下是显示确切问题的图像链接:

  • 在写字板中正确显示

  • RichTextBox控件中显示不正确

我用google搜索解决方案和第三方.net RTF控件没有成功。 我发现这个确切的问题在另一个论坛上没有回答(实际上这是图像的链接来自哪里),所以我希望堆栈溢出更好;-)

我首选的解决方案是使用能够正确呈现RTF的代码或第三方控件。 但是,我怀疑问题是RichTextBox控件只支持完整RTF规范的子集,因此另一个选项是直接修改RTF以删除不支持的控制代码或以其他方式修复RTF文件本身(在这种情况下任何信息)至于需要删除或修改哪些控制代码将是一个巨大的帮助)。

.NET中的Rich Text框非常错误。

在RTF中,定义表的方式实际上与您习惯使用HTML时的预期完全不同。

HTML:

Mycell

在RTF中,表格只是一系列段落,其中控制字定义行,单元格,边框。 表的开头/结尾没有组标记。

RTF:

 \trowd\trgraph \cellx1000 Mycell \cell\row\pard\par 

如果要在单元格内添加段落,可以使用\ par和control \ intbl(在表格中)来指示段落在表格内。

.NET RTB只能处理一小部分RTF控制字,并且不支持绝大多数可用命令。 根据事物的外观,\ intbl是它不支持的长控制字列表的一部分,如果它实际上在该点解析\ par,则显示被删除。

不幸的是,我没有解决方案,但我希望上面的小解释可以帮助你理解问题。

不要过分相信我的RTF样本。 它有效,但它绝对是骨干。 您可以从Microsoft的网站下载RTF规范: Word 2007 RTF规范 。

您可以使用旧的COM控件而不是新的.NET控件,还是需要“纯”的.NET解决方案?

换句话说,进入Visual Studio工具箱,右键单击,选择“选择项目”,查看“COM组件”选项卡并查看Microsoft Rich Textbox Control 6.0。

在这里回答我自己的问题,但仅仅是由于Joel和sylverdrag的帮助……

简短的回答是.Net和底层的COM RichTextBox都不支持表中的自动换行。 我最终敲了一个测试应用程序并同时使用COM和.Net RichTextBox控件,它们都表现出相同(破碎)的行为。

我还从sylverdrag提供的链接下载了RTF规范,在修改了MS Word和RichTextEdit控件中的手工制作的RTF文档之后,我可以确认TichTextBox没有正确支持\ intbl控制字 – 这是自动换行所必需的。表。

似乎有三种可能的解决方案:

  1. 使用TX文本控制 。 我已经使用试用版确认了这项工作,但价格昂贵 – 每位开发人员的价格为549美元。

  2. 使用Code Project上讨论的嵌入式MS Word实例。 请注意,代码项目中提供的代码示例并不是开箱即用的,但我确实让它与Office 2003和VS 2008一起使用。经过多次扫描我们遇到了意外的显示停止 – 我们希望文档是只读的所以我们保护()文件。 虽然这有效,但当用户尝试编辑文档时,MS Word“保护文档”侧栏会从控件的右侧弹出。 我们不能忍受这种情况而且我无法将其关闭(而且从谷歌搜索看起来我并不孤单)。

  3. 放弃RTF并使用HTML,然后在WebBrowser控件而不是RichTextEdit控件中呈现文档。 这是我们正在采取的选项,因为事实certificate源文档可以采用任何一种格式。

步骤1,使用旧的COM Microsoft Rich Textbox Control 6.0; 步骤2,制作Windows \ System32 \ MsftEdit.dll的副本,然后将其重命名为riched20.dll; 步骤3,将riched20.dll复制到您的应用程序文件夹,例如bin \ bebug。 这工作正常,表格显示正确。

Wordpad通常是丰富的编辑控件的一个非常薄的包装器,所以如果它正确显示那么Windows应该能够处理它。

也许您正在实例化富编辑控件的错误版本? 有很多,Windows继续提供较旧的向后兼容性。 http://msdn.microsoft.com/en-us/library/bb787873(VS.85).aspx

只需创建一个新的控件。 这对我来说可以。

 using System; using System.ComponentModel; using System.Windows.Forms; using System.Runtime.InteropServices; public class RichTextBox5 : RichTextBox { private static IntPtr moduleHandle; protected override CreateParams CreateParams { get { if (moduleHandle == IntPtr.Zero) { moduleHandle = LoadLibrary("msftedit.dll"); if ((long)moduleHandle < 0x20) throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not load Msftedit.dll"); } CreateParams createParams = base.CreateParams; createParams.ClassName = "RichEdit50W"; if (this.Multiline) { if (((this.ScrollBars & RichTextBoxScrollBars.Horizontal) != RichTextBoxScrollBars.None) && !base.WordWrap) { createParams.Style |= 0x100000; if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) { createParams.Style |= 0x2000; } } if ((this.ScrollBars & RichTextBoxScrollBars.Vertical) != RichTextBoxScrollBars.None) { createParams.Style |= 0x200000; if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) { createParams.Style |= 0x2000; } } } if ((BorderStyle.FixedSingle == base.BorderStyle) && ((createParams.Style & 0x800000) != 0)) { createParams.Style &= -8388609; createParams.ExStyle |= 0x200; } return createParams; } } // P/Invoke declarations [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern IntPtr LoadLibrary(string path); } 

这不是.net中提供的RitchText控件的问题。 一些Ritchtext规则(Ritchtext Synatax)在新版Ms-office(2007)中已被更改。 但.net中使用的组件无法更新以满足新规则,因此问题就会出现。

阿南德