Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Winforms RichTextBox中的两列_C#_Winforms_Printing_Richtextbox_Wysiwyg - Fatal编程技术网

C# Winforms 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

在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
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)。