【问题标题】:How to append \line into RTF using RichTextBox control如何使用 RichTextBox 控件将 \line 附加到 RTF
【发布时间】:2011-01-06 14:47:15
【问题描述】:

使用 Microsoft RichTextBox 控件时,可以像这样添加新行...

richtextbox.AppendText(System.Environment.NewLine); // appends \r\n

但是,如果您现在查看生成的 rtf,\r\n 字符将转换为 \par 而不是 \line

如何在生成的 RTF 中插入 \line 控制代码?

什么不起作用:

代币替换

黑客喜欢在字符串的末尾插入一个标记,然后在事后替换它,所以是这样的:

string text = "my text";
text = text.Replace("||" "|"); // replace any '|' chars with a double '||' so they aren't confused in the output.
text = text.Replace("\r\n", "_|0|_"); // replace \r\n with a placeholder of |0|

richtextbox.AppendText(text);

string rtf = richtextbox.Rtf;
rtf.Replace("_|0|_", "\\line"); // replace placeholder with \line
rtf.Replace("||", "|"); // set back any || chars to |

这几乎奏效了,如果你必须支持从右到左的文本,它就会崩溃,因为从右到左的控制序列总是在占位符的中间结束。

发送关键信息

public void AppendNewLine()
{
    Keys[] keys = new Keys[] {Keys.Shift, Keys.Return};
    SendKeys(keys);
}

private void SendKeys(Keys[] keys)
{
    foreach(Keys key in keys)
    {
        SendKeyDown(key);
    }
}

private void SendKeyDown(Keys key)
{
    user32.SendMessage(this.Handle, Messages.WM_KEYDOWN, (int)key, 0);
}

private void SendKeyUp(Keys key)
{
    user32.SendMessage(this.Handle, Messages.WM_KEYUP, (int)key, 0);
}

这也最终被转换为 \par

有没有办法将消息直接发布到 msftedit 控件以插入控制字符?

我完全被难住了,有什么想法吗?感谢您的帮助!

【问题讨论】:

  • 您犯了一个错误:在第一阶段,您将两个 || 替换为一个,而不是相反。

标签: c# richtextbox


【解决方案1】:

就我的测试显示而言,添加 Unicode“行分隔符”(U+2028) 确实有效:

private void Form_Load(object sender, EventArgs e)
{
    richText.AppendText("Hello, World!\u2028");
    richText.AppendText("Hello, World!\u2028");
    string rtf = richText.Rtf;
    richText.AppendText(rtf);
}

当我运行程序时,我得到:

Hello, World!
Hello, World!
{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Courier New;}}
{\colortbl ;\red255\green255\blue255;}
\viewkind4\uc1\pard\cf1\f0\fs17 Hello, World!\line Hello, World!\line\par
}

它确实添加了\line 而不是\par

【讨论】:

  • 请注意,mono 的 RichTextBox 仿真相当损坏,并且除其他不兼容外,不理解行分隔符。它在文本中显示为方框字符。
  • 这对我来说就像是一种魅力,它让我能够消除我们现有的可怕黑客攻击。我们的客户会感谢您的!
  • 对我不起作用。一种 '?'出现在文件中
  • 如果您正在编辑 RTF 原始代码,为什么不将“\line”标签替换/添加到代码中?
【解决方案2】:

由于您想使用不同的 RTF 代码,我认为您可能需要忘记简单的 AppendText() 方法并直接操作 RichTextBox 的 .Rtf 属性。这是一个示例(经过测试)来演示:

RichTextBox rtb = new RichTextBox();
//this just gets the textbox to populate its Rtf property... may not be necessary in typical usage
rtb.AppendText("blah");
rtb.Clear();

string rtf = rtb.Rtf;

//exclude the final } and anything after it so we can use Append instead of Insert
StringBuilder richText = new StringBuilder(rtf, 0, rtf.LastIndexOf('}'), rtf.Length /* this capacity should be selected for the specific application */);

for (int i = 0; i < 5; i++)
{
    string lineText = "example text" + i;
    richText.Append(lineText);
    //add a \line and CRLF to separate this line of text from the next one
    richText.AppendLine(@"\line");
}

//Add back the final } and newline
richText.AppendLine("}");


System.Diagnostics.Debug.WriteLine("Original RTF data:");
System.Diagnostics.Debug.WriteLine(rtf);

System.Diagnostics.Debug.WriteLine("New Data:");
System.Diagnostics.Debug.WriteLine(richText.ToString());


//Write the RTF data back into the RichTextBox.
//WARNING - .NET will reformat the data to its liking at this point, removing
//any unused colors from the color table and simplifying/standardizing the RTF.
rtb.Rtf = richText.ToString();

//Print out the resulting Rtf data after .NET (potentially) reformats it
System.Diagnostics.Debug.WriteLine("Resulting Data:");
System.Diagnostics.Debug.WriteLine(rtb.Rtf);

输出:

原始 RTF 数据:

{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}} \viewkind4\uc1\pard\f0\fs17\par }

新的 RTF 数据:

{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}} \viewkind4\uc1\pard\f0\fs17\par 示例 text0\line 示例 text1\line 示例 text2\line 示例 text3\line 示例 text4\line }

生成的 RTF 数据:

{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}} \viewkind4\uc1\pard\f0\fs17\par 示例 text0\line 示例 text1\line 示例 text2\line 示例 text3\line 示例 text4\par }

【讨论】:

    【解决方案3】:

    如果您使用段落写入richtextbox,您可以使用 LineBreak() 相同的代码,如下所示

    Paragraph myParagraph = new Paragraph();
    FlowDocument myFlowDocument = new FlowDocument();
    
    // Add some Bold text to the paragraph
    myParagraph.Inlines.Add(new Bold(new Run(@"Test Description:")));
    myParagraph.Inlines.Add(new LineBreak()); // to add a new line use LineBreak()
    myParagraph.Inlines.Add(new Run("my text"));
    myFlowDocument.Blocks.Add(myParagraph);
    myrichtextboxcontrolid.Document = myFlowDocument;
    

    希望这会有所帮助!

    【讨论】:

    • 完美解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多