C# Winforms RichTextBox中的两列
在C#中,我需要能够在单个RichTextBox中至少显示两列。就我而言,它可能看起来像这样:C# Winforms RichTextBox中的两列,c#,winforms,printing,richtextbox,wysiwyg,C#,Winforms,Printing,Richtextbox,Wysiwyg,在C#中,我需要能够在单个RichTextBox中至少显示两列。就我而言,它可能看起来像这样: 1+1 2 70*8+5 565 1000000-300000 700000 76-10 66 SelectionTabs = new int[] { 0, 500 }; 对于左列中的每个“问题”,都会有相应的答案 “显而易见”的解决方案是使用如下选项卡: 1+1 2 70*8+5 565 1
1+1 2
70*8+5 565
1000000-300000 700000
76-10 66
SelectionTabs = new int[] { 0, 500 };
对于左列中的每个“问题”,都会有相应的答案
“显而易见”的解决方案是使用如下选项卡:
1+1 2
70*8+5 565
1000000-300000 700000
76-10 66
SelectionTabs = new int[] { 0, 500 };
(或者在原始Rtf中将\deftab设置为大约3000)
这一切都很好,直到左列输入本身包含选项卡。在这种情况下,一切都会变成梨形。我不介意插入多个制表位,但当输入包含文本时,有时会“超过”某个特定制表位,这将无法正常工作。检测并正确解释这一点不仅很难做到,而且由于打印时出现“几乎但不完全是所见即所得”的结果以及标签如何受到影响,因此也充满了风险
另一个想法是拥有一个全局选项卡大小(在Rtf中使用\deftab),然后计算在左列的每一行之后应该自动插入多少选项卡(基于左列中最长的行)。这种方法的问题是,虽然屏幕上的东西看起来很棒,但当涉及到打印时,右栏有一些小故障。所谓“故障”,我的意思是每20行中大约有1行会有“丢失”或“额外”选项卡。这是因为即使在我学习了本教程之后,打印也不完全是所见即所得:
可以这么说,与RichTextBox在屏幕上的视图相比,即使打印中有几个像素/点偏离,也会对选项卡的位置产生重大影响
我还尝试在Rtf中的一行中途更改tabstop位置,但不幸的是,这样的控制代码是从该行开始应用的,尽管它位于Rtf中
我也从中梳理了Rtf规范,似乎对此我无能为力。C#的RichTextBox似乎与表不太合拍(这是另一个潜在的解决方案)。也有Rtf列,但即使支持Rtf列,它们也可能不会有帮助,因为第一列填充后将切换到同一张纸上的第二列(而不是保持第一列并转到第二页,这是我想要的)
我花了这么多时间来解决这个问题,我完全不知所措。如此简单的事情,要想做得好,实际上是非常棘手的。除非我错过了一些明显的东西
----------------编辑1:
这需要使用非固定宽度字体,所以我不能只使用空格填充。技巧很简单:我最近也做了同样的事情(嗯,几乎是这样)-我必须创建一个文本文件 这给人的印象是它有多个列(在一个文本文件中?sheesh) 诀窍是什么?填充物 假设您具有前面所述的值
1+1 2
70*8+5 565
1000000-300000 700000
76-10 66
现在,您只需设置左栏的宽度(字符),右栏的宽度。假设两个宽度都是30个字符
现在需要做的就是构造一行,如以下伪代码所示:
BEGIN-BUILD-TEXT
FOR EACH PAIR X, Y
STRING S1 = X.PADRIGHT(30);
STRING S2 = Y.PADRIGHT(30);
WRITE_LINE_TO_TEXTBOX(S1 + S2);
这样,列将左对齐并具有固定的宽度
为我工作
编辑:您的
RichTextBox
应该使用固定宽度字体(所有字符的宽度都相同)。此解决方案很难看,但它可以工作。要在RichTextBox中有两列,即使在打印时对齐也需要正确,并且左列本身可能包含选项卡,需要执行以下操作。(可能存在另一种解决方案,但在研究了几乎几天之后,什么也没有出现。)
一般的想法是从RichTextBox中现有的Rtf/Text创建一个新的Rtf字符串。
新的Rtf需要在每一行中定义一组不同的制表位。要了解制表位是什么,请打开写字板,看看如何单击标尺来定义制表位。无论如何,每个制表位都是使用GetPositionFromCharIndex(charIndex)从原始RichTextBox输入测量的。您可能希望将这些内容存储在整数的2D数组中(行、制表符编号)。由于Rtf制表位以twips为单位,因此需要使用以下公式将GetPositionFromCharIndex()返回值(像素)转换为twips:
Graphics g = this.CreateGraphics();
double twips = pixels * 1440.0 / g.DpiX; // usually g.DpiX is 96
g.Dispose();
如果左列有3个制表符,则需要相应地插入3个制表符(\tx)。默认情况下,这些值应为720的倍数(+1表示像素边距)。然后需要将最后一个制表位(第四个制表位)设置为所需的第二列位置,并将额外的最终制表位添加到Rtf(使用\tab)。此制表位值是通过获取整个左列中最长行的结尾位置+少量填充而得出的。在Rtf中的最后一个选项卡之后,插入该行的右栏“answer”。确保您也为该行插入“\pard”,否则制表位将不起作用。每一行都以“\par”结尾,为了便于编码,我认为制表符可以位于Rtf中该行的任何位置
好的,一旦您按照上面的说明进行操作,尽管它在屏幕上看起来很好(2个完美的列),但有时它在打印出来时仍然无法正常工作(使用打印预览检查),这是因为RTB打印几乎但不完全是wysiwig性质。然而,有一个(笨拙的)解决办法。首先,按照本教程进行打印:
现在的诀窍是将每个tabstop“拉伸”至少1.03倍。我使用1.05,但1.1可能更安全。之所以需要这样做,是因为(至少我发现)打印将文本水平拉伸得非常轻微。大多数情况下,这是无害的,但有时会对标签造成严重破坏。通过将每个tabstop位置拉伸1.05,可以确保tabstop之间包含的文本不会“溢出”到下一个tabstop(从而导致随后的文本错误地跳转到下一个tab)。