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

发布于 2024-07-13 15:50:55 字数 1087 浏览 5 评论 0原文

可能的重复:
为什么 Richtextbox 无法正确显示此表格? < /p>

我们Visual Studio 2008 中的 Windows.Forms.RichTextBox 控件出现问题。

我们正在尝试在 Windows 窗体应用程序 (.NET 3.5) 中显示第三方以 RTF 文件形式提供的文本。 在此 RTF 文本文件中有一些表格,其中包含跨多行的文本。 打开时,RTF 文件会正确显示

当使用写字板或 Word 2003 打开 RTF 文件时,RTF 文件可以正确显示。但是,当我们将 RTF 文件加载到 RichTextBox 控件中或复制并 。 将整个文本(包括表格)粘贴到控件中,表格无法正确显示 - 单元格只是单行,没有换行。

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

我已在 google 上搜索解决方案和第 3 方 .net RTF 控件,但没有成功。 我发现另一个论坛上提出了这个确切的问题,但没有答案(事实上,这就是图像链接的来源),所以我希望堆栈溢出做得更好;-)

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

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.

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.

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.

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 ;-)

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夏至、离别 2024-07-20 15:50:55

.NET 的富文本框有很多错误。

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

HTML:

<table>
<tr>
    <td>Mycell</td>
</tr>
</table>

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

RTF:

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

如果要在单元格内添加段落,请使用 \par 和控件 \intbl (在表格中)来指示该段落位于表格内。

.NET RTB 只能处理 RTF 控制字的一小部分,并且不支持绝大多数可用命令。 从表面上看, \intbl 是它不支持的一长串控制字的一部分,如果它实际上解析了 \par 此时,显示就会被丢弃。

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

不要太相信我的 RTF 样本。 它确实有效,但绝对是简单的。 您可以从 Microsoft 网站下载 RTF 规范:
Word 2007 RTF 规范。

The Rich Text box from .NET is extremely buggy.

In RTF, the way a table is defined is actually quite different from what you could expect if you are used to 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:

\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.

.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.

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.

人间☆小暴躁 2024-07-20 15:50:55

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

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

Can you use the old COM control instead of the new .NET control, or do you require a "pure" .NET solution?

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.

初见终念 2024-07-20 15:50:55

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

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

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

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

  1. 使用TX Text Control 。 我已确认该功能可以使用试用版,但价格昂贵 - 每个开发人员的起价为 549 美元。

  2. 使用嵌入式 MS Word 实例,如代码项目。 请注意,代码项目上提供的代码示例并不是开箱即用的,但我确实让它与 Office 2003 和 Office 2003 一起工作。 VS 2008。经过一番折腾后,我们遇到了一个意想不到的问题——我们希望文档是只读的,所以我们 Protect() 文档。 虽然此方法有效,但当用户尝试编辑文档时,MS Word“保护文档”侧栏会从控件的右侧弹出。 我们无法忍受这一点,而且我无法将其关闭(通过谷歌搜索看来我并不孤单)。

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

Answering my own question here, but only due to the help from Joel and 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.

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.

There appear to be three possible solutions:

  1. Use TX Text Control. I have confirmed this works using a trial version but it is expensive - prices start at US$549 per developer.

  2. 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).

  3. 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.

只是我以为 2024-07-20 15:50:55

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

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.

江城子 2024-07-20 15:50:55

写字板通常是丰富的编辑控件的一个非常薄的包装,因此如果它在那里正确显示,那么 Windows 应该能够处理它。

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

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.

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

爱冒险 2024-07-20 15:50:55

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

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);

}

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);

}
信仰 2024-07-20 15:50:55

这不是.net中提供的RitchText Control的问题。 新版本的 Ms-office (2007) 中更改了一些 Ritchtext 规则(Ritchtext Synatax)。 但是 .net 中使用的组件无法更新以适应新规则,因此会出现此问题。

阿南德

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.

Anand

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文