C# RichTextBox 控件中的损坏表格(自动换行)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/510093/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Broken tables in RichTextBox control (word wrap)
提问by Ben Robbins
Possible Duplicate:
Why isn't the richtextbox displaying this table properly?
可能的重复:
为什么富文本框不能正确显示此表?
We are having problems with the Windows.Forms.RichTextBox control in Visual Studio 2008.
我们在 Visual Studio 2008 中遇到了 Windows.Forms.RichTextBox 控件的问题。
We are trying to display text supplied as an RTF file by a 3rd party in a windows forms application (.NET 3.5). In this RTF text file there are tables, which contain text that spans multiple lines. The RTF file displays correctly when opened with either WordPad or Word 2003.
我们正在尝试在 windows 窗体应用程序 (.NET 3.5) 中显示由第 3 方提供的 RTF 文件文本。在这个 RTF 文本文件中有表格,其中包含跨越多行的文本。RTF 文件在使用 WordPad 或 Word 2003 打开时正确显示。
However, when we load the RTF file into the RichTextBox control, or copy & paste the whole text (including the table) into the control, the table does not display correctly - the cells are only single line, without wrapping.
但是,当我们将 RTF 文件加载到 RichTextBox 控件中,或者将整个文本(包括表格)复制并粘贴到控件中时,表格无法正确显示 - 单元格只是单行,没有换行。
Here are links to images showing the exact problem:
以下是显示确切问题的图像链接:
I have googled for solutions and 3rd party .net RTF controls without success. I have found this exact problem asked on another forum without an answer (in fact that's where the link to the images come from) so I'm hoping stack overflow does better ;-)
我在谷歌上搜索了解决方案和 3rd 方 .net RTF 控件,但没有成功。我在另一个论坛上发现了这个确切的问题而没有答案(实际上这是图像链接的来源)所以我希望堆栈溢出会更好;-)
My preferred solution would be to use code or a 3rd party control that can correctly render the RTF. However, I suspect the problem is that the RichTextBox control only supports a subset of the full RTF spec, so another option would be to modify the RTF directly to remove the unsupported control codes or otherwise fix the RTF file itself (in which case any information as to what control codes need to be removed or modified would be a huge help).
我的首选解决方案是使用可以正确呈现 RTF 的代码或第 3 方控件。但是,我怀疑问题在于 RichTextBox 控件仅支持完整 RTF 规范的一个子集,因此另一种选择是直接修改 RTF 以删除不受支持的控件代码或以其他方式修复 RTF 文件本身(在这种情况下,任何信息至于需要删除或修改哪些控制代码将是一个巨大的帮助)。
回答by Mark Ransom
Wordpad is generally a very thin wrapper over the rich edit control, so if it appears properly there then Windows should be able to handle it.
写字板通常是富编辑控件的一个非常薄的包装器,因此如果它在那里正确显示,那么 Windows 应该能够处理它。
Perhaps you're instantiating the wrong version of the rich edit control? There have been many, and Windows continues to supply the older ones for backwards compatibility. http://msdn.microsoft.com/en-us/library/bb787873(VS.85).aspx
也许您正在实例化错误版本的 Rich Edit 控件?有很多,Windows 继续提供旧的以实现向后兼容性。 http://msdn.microsoft.com/en-us/library/bb787873(VS.85).aspx
回答by Joel Spolsky
Can you use the old COM control instead of the new .NET control, or do you require a "pure" .NET solution?
您可以使用旧的 COM 控件而不是新的 .NET 控件,还是需要“纯”的 .NET 解决方案?
In other words, go into the Visual Studio toolbox, right click, choose "Choose Items", look in the COM Components tab and check Microsoft Rich Textbox Control 6.0.
换句话说,进入 Visual Studio 工具箱,右键单击,选择“选择项目”,查看 COM 组件选项卡并选中 Microsoft Rich Textbox Control 6.0。
回答by Sylverdrag
The Rich Text box from .NET is extremely buggy.
.NET 中的富文本框非常有缺陷。
In RTF, the way a table is defined is actually quite different from what you could expect if you are used to HTML.
在 RTF 中,定义表格的方式实际上与您使用 HTML 时所期望的完全不同。
HTML:
HTML:
<table>
<tr>
<td>Mycell</td>
</tr>
</table>
In RTF, a table is simply a series of paragraphs with control words defining rows, cells, borders. There is no group tag for the start/end of a table.
在 RTF 中,表格只是一系列带有定义行、单元格、边框的控制字的段落。表的开始/结束没有组标签。
RTF:
格式:
\trowd\trgraph \cellx1000 Mycell \cell\row\pard\par
If you want to add a paragraph inside a cell, you use \par and the control \intbl (in table) to indicate the paragraph is inside the table.
如果您想在单元格内添加一个段落,您可以使用 \par 和控件 \intbl(在表格中)来指示该段落在表格内。
.NET RTB can handle only a very small subset of RTF control words and doesn't support the vast majority of available commands. By the looks of things, \intbl is part of the long long list of control words it doesn't support, and if it actually parses \par at that point, the display is trashed.
.NET RTB 只能处理非常小的 RTF 控制字子集,并且不支持绝大多数可用命令。从表面上看, \intbl 是它不支持的一长串控制字的一部分,如果它在那时真正解析 \par,则显示会被破坏。
Unfortunately, I don't have a solution for that but I hope the small explanation above helps you make some sense of the problem.
不幸的是,我没有解决方案,但我希望上面的小解释可以帮助您理解这个问题。
Don't put too much faith on my RTF sample. It works, but it's absolutely bare-bones. You can download the RTF specifications from Microsoft's website: Word 2007 RTF specs.
不要太相信我的 RTF 样本。它有效,但它绝对是简单的。您可以从 Microsoft 的网站下载 RTF 规范: Word 2007 RTF 规范。
回答by Ben Robbins
Answering my own question here, but only due to the help from Joel and sylverdrag...
在这里回答我自己的问题,但只是由于 Joel 和 sylverdrag 的帮助......
The short answer is that both the .Net and underlying COM RichTextBox do not support word wrap in tables. I ended up knocking up a test application and using both the COM and .Net RichTextBox controls and they both exhibited the same (broken) behaviour.
简短的回答是 .Net 和底层 COM RichTextBox 都不支持表格中的自动换行。我最终敲了一个测试应用程序并同时使用 COM 和 .Net RichTextBox 控件,它们都表现出相同的(损坏的)行为。
I also downloaded the RTF spec from the link supplied by sylverdrag and after tinkering with hand-made RTF documents in MS Word and RichTextEdit controls, I can confirm that TichTextBox does not correctly support the \intbl control word - which is required for word wrap in tables.
我还从 sylverdrag 提供的链接下载了 RTF 规范,在修改 MS Word 和 RichTextEdit 控件中的手工 RTF 文档后,我可以确认 TichTextBox 不正确支持 \intbl 控制字 - 这是自动换行所需的表。
There appear to be three possible solutions:
似乎有三种可能的解决方案:
Use TX Text Control. I have confirmed this works using a trial version but it is expensive - prices start at US$549 per developer.
Use an embedded MS Word instance as discussed on Code Project. Note that the code example provided on Code Project didn't work out of the box but I did get it working with Office 2003 & VS 2008. After much mucking around we hit an unexpected show stopper - we want the document to be read-only so we Protect() the document. While this works, when a user tries to edit the document the MS Word "Protect Document" side bar pops out from the right hand side of the control. We can't live with this and I was not able to turn it off (and from googling it looks like I'm not alone).
Give up on RTF and use HTML instead and then render the document in a WebBrowser control instead of a RichTextEdit control. That is the option we are taking as it turns out the source document is available in either format.
使用TX 文本控制。我已经使用试用版确认此功能有效,但价格昂贵 - 每位开发人员的起价为 549 美元。
使用Code Project 中讨论的嵌入式 MS Word 实例。请注意,Code Project 上提供的代码示例并没有立即可用,但我确实让它在 Office 2003 和 VS 2008 中工作。经过一番折腾之后,我们遇到了一个意想不到的障碍——我们希望文档是只读的所以我们 Protect() 文档。虽然这有效,但当用户尝试编辑文档时,MS Word“保护文档”侧栏会从控件的右侧弹出。我们不能忍受这个,我无法将其关闭(从谷歌搜索来看,我并不孤单)。
放弃 RTF 并改用 HTML,然后在 WebBrowser 控件而不是 RichTextEdit 控件中呈现文档。这是我们正在采取的选项,因为源文档可以以任何一种格式使用。
回答by Ben Robbins
Step 1, Use the old COM Microsoft Rich Textbox Control 6.0; Step 2, Make a copy of Windows\System32\MsftEdit.dll and then rename it to riched20.dll; Step 3, Copy riched20.dll to your app folder such as bin\bebug. This works fine, table displays correctly.
第一步,使用旧的COM Microsoft Rich Textbox Control 6.0;第二步,复制Windows\System32\MsftEdit.dll,然后重命名为riched20.dll;第 3 步,将riched20.dll 复制到您的应用程序文件夹,例如bin\bebug。这工作正常,表格显示正确。
回答by Anand
This is not a issue of RitchText Control provided in .net . some Ritchtext rules (Ritchtext Synatax) has been changed in new version of Ms-office (2007). however the component used in .net cannot update to cater the new rules so the issue occours.
这不是 .net 中提供的 RitchText Control 的问题。在新版 Ms-office (2007) 中更改了一些 Ritchtext 规则 (Ritchtext Synatax)。但是,.net 中使用的组件无法更新以适应新规则,因此会出现此问题。
Anand
阿南德
回答by Vil
Just create a new Control. It works fine for me.
只需创建一个新控件。这对我来说可以。
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);
}