【问题标题】:RichTextBox Newline Conversion?RichTextBox 换行符转换?
【发布时间】:2011-08-15 16:45:51
【问题描述】:

我正在使用 WinForms RichTextBox。似乎当 RichTextBox 在表单上时,\r\n 被转换为\n。这是一个测试:

我有两个富文本框。一个是richTextBox1,放在表单上:

  this.richTextBox1 = new System.Windows.Forms.RichTextBox();
  this.SuspendLayout();
  // 
  // richTextBox1
  // 
  this.richTextBox1.Location = new System.Drawing.Point(37, 12);
  this.richTextBox1.Name = "richTextBox1";
  this.richTextBox1.Size = new System.Drawing.Size(100, 96);
  this.richTextBox1.TabIndex = 0;
  this.richTextBox1.Text = "";

另一个是rtb,是我现场创建的。当我运行这段代码时(在表单的加载事件中):

  var rtb = new RichTextBox();
  string enl = "Cheese" + Environment.NewLine + "Whiz";
  rtb.Text = enl;
  string ncr = rtb.Text;
  MessageBox.Show(string.Format("{0}{1}{2}{3}---{4}{5}{6}{7}{8}{9}",
                                enl.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                ncr.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                Environment.NewLine,
                                (enl == ncr), Environment.NewLine,
                                enl.Contains(Environment.NewLine), Environment.NewLine,
                                ncr.Contains(Environment.NewLine)));
  /*
  Cheese\r\nWhiz
  Cheese\r\nWhiz
  ---
  True
  True
  True
  */
  richTextBox1.Text = enl;
  string ncr2 = richTextBox1.Text;
  MessageBox.Show(string.Format("{0}{1}{2}{3}---{4}{5}{6}{7}{8}{9}",
                                enl.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                ncr2.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                Environment.NewLine,
                                (enl == ncr2), Environment.NewLine,
                                enl.Contains(Environment.NewLine), Environment.NewLine,
                                ncr2.Contains(Environment.NewLine)));
  /*
  Cheese\r\nWhiz
  Cheese\nWhiz
  ---
  False
  True
  False
  */

RichTextBox 似乎表现出一些奇怪的行为。当我将包含\r\n 的文本放入刚刚创建的框中时,它保持不变(仍然包含\r\n)。但是,当我将包含 \r\n 的文本放入表单的框中时,\r\n 会变成 \n

我的问题:这种行为是否有原因(\r\n->\n)?这种行为是否记录在某处?我可以指望它总是这样吗?

我在此处发布的案例是我试图找出我在另一个项目中使用我的一个表单时遇到的问题,因此我非常感谢有关此问题的任何意见。

【问题讨论】:

  • 记得以前看过这个,但是我只是绕过它:-/期待看到答案

标签: c# .net winforms richtextbox


【解决方案1】:

RichTextBox.Text 属性正在根据RichTextBox.Rtf 属性中指定的 Rtf 格式代码将分配的字符串转换为 rtf 文档。由于“rtb”实例未初始化,“Rtf”格式代码为空,它只是回显您的输入。 'rtb' 初始化后,它包含一个空的 rtf 文档(带有格式代码),这与 'richTextBox1' 的行为相同(且正确)。

结果:

preinit  rtb.Rtf : ''
postinit rtb.Rtf : '"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft Sans Serif;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs17\\par\r\n}\r\n"'
richTextBox1.Rtf : '"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft Sans Serif;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs17\\par\r\n}\r\n"'
richtextBox1.Rtf with cheese : '"{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft Sans Serif;}}\r\n\\viewkind4\\uc1\\pard\\lang1033\\f0\\fs17 Cheese\\par\r\nWhiz\\par\r\n}\r\n"'

代码:

void Form1_Load(object sender, EventArgs e)
{
    TestIt();
}
public void TestIt()
{
    string enl = "Cheese" + Environment.NewLine + "Whiz";

    RichTextBox rtb = new RichTextBox();
    MessageBox.Show("preinit rtb.Rtf : '" + rtb.Rtf + "'");
    this.Controls.Add(rtb);
    MessageBox.Show("postinit rtb.Rtf : '" + rtb.Rtf + "'");
    MessageBox.Show("richTextBox1.Rtf : '" + richTextBox1.Rtf + "'");

    rtb.Text = enl;
    string ncr = rtb.Text;
    MessageBox.Show(string.Format("rtb: {0}{1}{2}{3}---{4}{5}{6}{7}{8}{9}",
                                  enl.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                  ncr.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                  Environment.NewLine,
                                  (enl == ncr), Environment.NewLine,
                                  enl.Contains(Environment.NewLine), Environment.NewLine,
                                  ncr.Contains(Environment.NewLine)));
    /*
    Cheese\r\nWhiz
    Cheese\nWhiz
    ---
    False
    True
    False
    */
    richTextBox1.Text = enl;
    MessageBox.Show("richTextBox1.Rtf with cheese : '" + richTextBox1.Rtf + "'");
    string ncr2 = richTextBox1.Text;
    MessageBox.Show(string.Format("richTextBox1: {0}{1}{2}{3}---{4}{5}{6}{7}{8}{9}",
                                  enl.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                  ncr2.Replace("\n", "\\n").Replace("\r", "\\r"), Environment.NewLine,
                                  Environment.NewLine,
                                  (enl == ncr2), Environment.NewLine,
                                  enl.Contains(Environment.NewLine), Environment.NewLine,
                                  ncr2.Contains(Environment.NewLine)));
    /*
    Cheese\r\nWhiz
    Cheese\nWhiz
    ---
    False
    True
    False
    */
}

【讨论】:

  • 换行符是\n是RTF规范的一部分吗?
  • 我相信这更多地与 rtf 文件字符集通常是 '\ansi' 和 getter 使用的 unicode 代码页 '\ansicpg1252' 的事实有关。输入文本中的换行符根据 rtf 规范编码为 rtf 段落分隔符“\par”,并由 unicode rtf 代码页作为换行符重新发出。
  • 在上面的代码中添加了一个 MessageBox 来演示段落编码。
  • 那么我可以指望这种事情总是会发生吗?
  • 除非您的代码手动更改 rtf 文档中的 unicode 编码参数,否则我认为标准的默认行为是一个安全的假设。就像汉斯在下面所说的“这就是控件的工作原理。”
【解决方案2】:
  var rtb = new RichTextBox();
  string enl = "Cheese" + Environment.NewLine + "Whiz";
  rtb.Text = enl;

这是 Text 属性工作方式的副作用。它缓存在 Control.Text 中,实际的原生 Windows 控件在创建之前不会更新。问题是,您的 rtb 从未发生过这种情况。您没有将其添加到表单中,因此未创建本机控件。 .NET 中典型的惰性资源分配模式。因此,您正在读取缓存的值,而不是控件中的值。

要看到这一点,修改代码以强制创建控件:

        var rtb = new RichTextBox();
        rtb.CreateControl();
        string enl = "Cheese" + Environment.NewLine + "Whiz";
        rtb.Text = enl;

你会看到\r\n 现在被翻译成\n。不要忘记 Dispose() 控件。

【讨论】:

  • 好吧,这很有道理……但我更关心为什么 \r\n 改为 \n
  • 这就是控件的工作原理。 RTB 有很多里程数。
猜你喜欢
  • 1970-01-01
  • 2013-12-10
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
  • 2019-10-14
  • 1970-01-01
  • 2011-02-06
相关资源
最近更新 更多