Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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# 如何将长文本拆分为多个片段/页面以适合RichTextBox?_C#_Winforms_Richtextbox - Fatal编程技术网

C# 如何将长文本拆分为多个片段/页面以适合RichTextBox?

C# 如何将长文本拆分为多个片段/页面以适合RichTextBox?,c#,winforms,richtextbox,C#,Winforms,Richtextbox,在使用WinForm应用程序时,我想将长文本(仅字符、无图像、无特殊格式)拆分为多个部分(页面),以便将它们放入RichTextBox 问题是RichTextBox不支持多页。 我必须编写自己的算法(某种DP编程)来分割文本。 目前,我正在使用TextRenderer.MeasureText()检查字符串是否可以放入富文本框,例如: bool canfit(String str) { Size rbx_size = new Size(rbx.Width, rbx.Height);

在使用
WinForm
应用程序时,我想将长文本(仅字符、无图像、无特殊格式)拆分为多个部分(页面),以便将它们放入
RichTextBox

问题是
RichTextBox
不支持多页。

我必须编写自己的算法(某种DP编程)来分割文本。

目前,我正在使用
TextRenderer.MeasureText()
检查字符串是否可以放入富文本框,例如:

bool canfit(String str)
{
    Size rbx_size = new Size(rbx.Width, rbx.Height);
    Size sz = TextRenderer.MeasureText(str, rbx.font, rbx_size, TextFormatFlags.WordBreak | TextFormatFlags.GlyOverhangPadding)
    return (sz.Height < rbx_size.Height);
}
bool canfit(字符串str)
{
尺寸rbx_尺寸=新尺寸(rbx.宽度,rbx.高度);
Size sz=TextRenderer.MeasureText(str、rbx.font、rbx_Size、TextFormatFlags.WordBreak | TextFormatFlags.GlyOverhangPadding)
返回(深浅高度
它不太好用,因为我认为上面的函数不准确


我想知道是否有一个简单的方法来做这件事?谢谢。

我不确定,我没有测试代码,但我希望它可以帮助您,至少会给您一个想法

将字体大小pt转换为px

Float points = 72; // each point in pixels 
Float fontSize = 12; // font size
Float dpi = 96; // find screen dpi (96 is very common I know)
Float px = fontsize * dpi / points; // each lines need px (exp: 16)
查找文本中的行数(exp:200行)

我们在第1步和第2步找到了行数以及每行需要多少像素,因此我们可以找到分隔符位置,以便在相关行中标记文本

Float totalTextPixels = lineCount * px;
Float textFieldHeight = 200; // for example
Float eachSplitLine = totalTextPixels / textFieldHeight;
再绕一圈

var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
    while (reader.ReadLine() != null)
    { 
        lineCount++;
        if(lineCount == eachSplitLine){
            // Put a deliminiter here (I don't know how)
            // for example | (pipe)
            lineCount = 0;
        }
    }
}
并用|

我知道这是不健全的和教授的解决方案,这只是一个想法


祝你过得愉快。

按照我的解释,提议的问题是将源文档的文本拆分为若干子字符串(页面),例如每个子字符串可以放入
RichTextBox
客户端区域,而无需生成/需要滚动条。

因此,第一项任务是计算给定文档必须拆分到的页面数。

这些方法是常用的工具。
在执行计算时,必须指示类包装文本(如RichTextBox控件所示),排除任何填充,并在TextBox类型控件编辑区域中填充字符串。

然后,主标志将是:

TextFormatFlags.WordBreak | TextFormatFlags.NoPadding | TextFormatFlags.TextBoxControl;
下一个任务是计算RichTextBox控件的客户端区域中可以容纳多少个字母/符号,这样就不需要滚动条了。

Winforms
RichTextBox
控件不提供任何特定工具,但非特定工具足以执行此计算。

请注意,(从TextBoxBase派生) 仅报告原始文本行拆分(预期为行 feed),而不是内部换行生成的行。

但是,TextBoxBase和可组合使用以获得相同的结果:
知道ClientArea中可以容纳多少行,下一行的第一个字符将比ClientArea中最后可见行的最后一个字符多一个字符(空格不换行)。
然后,重复此步骤,直到有足够的线条填充客户区。最后一页将包含
[总行数]/[每页行数]

此过程结果的可视化表示:


用于计算源文档大小和拆分文本的基本任务的示例代码。用于创建示例图像的完整源代码:

string Document=“[SomeDocumentText]”;
列表页=新列表();
TextFormatFlags flags=TextFormatFlags.Top | TextFormatFlags.Left|
TextFormatFlags.WordBreak | TextFormatFlags.NoPadding |
TextFormatFlags.TextBoxControl;
Size textSize=TextRenderer.MeasureText(文档,richTextBox1.Font,richTextBox1.ClientSize,标志);
int NumberOfPages=textSize.Height/richTextBox1.ClientSize.Height;
如果(textSize.Height>richTextBox1.Height)
{
richTextBox1.Text=文档;
richTextBox1.Update();
//显示的行数
int FirstCharOfLastShownLine=richTextBox1.GetCharIndexFromPosition(新点(0,richTextBox1.ClientSize.Height));
int shownline=richTextBox1.GetLineFromCharIndex(最后一个shownline的第一个字符);
int totalines=richTextBox1.GetLineFromCharIndex(richTextBox1.Text.Length-1);
对于(int p=0;ptotalines)?totalines:FirstLineOfNextPage;
int LastCharOfPage=(下一页的第一行<总计)
?richTextBox1.GetFirstCharIndexFromLine(下一页的第一行)-1
:richTextBox1.Text.Length;
Add(richTextBox1.Text.Substring(FirstCharOfPage,LastCharOfPage-FirstCharOfPage));
}
}
其他的
{
页数。添加(文件);
}
richTextBox1.Text=Pages.First();

如果您能提供一个示例和您迄今为止的尝试,将非常有帮助。请指定页面。比如说,它的行数是
N
还是更少?最多
C
个字符?以上规则的组合?不允许编辑helpful@zackraiyan还有你的评论。@AhmedOsama我认为zack的评论很有道理,而且对OP和问题编辑也很有帮助,因为这个问题仍然没有帮助人们理解什么是基本要求。@camino你太酷了!非常感谢。代码“LastCharOfPage-FirstCharOfPage”中有一个拼写错误,应该是“LastCharOfPage-FirstCharOfPage+1”。除此之外,它工作得很好,非常感谢!。今天我注意到,如果文档非常大,UI将冻结。似乎我无法将代码放入工作线程,因为大多数函数都依赖于richtextbox。有什么建议吗?@camino嗯,我认为繁重的工作(解析文本)可以
TextFormatFlags.WordBreak | TextFormatFlags.NoPadding | TextFormatFlags.TextBoxControl;
string Document = "[SomeDocumentText]";

List<string> Pages = new List<string>();
TextFormatFlags flags = TextFormatFlags.Top | TextFormatFlags.Left |
                        TextFormatFlags.WordBreak | TextFormatFlags.NoPadding | 
                        TextFormatFlags.TextBoxControl;

Size textSize = TextRenderer.MeasureText(Document, richTextBox1.Font, richTextBox1.ClientSize, flags);
int NumberOfPages = textSize.Height / richTextBox1.ClientSize.Height;

if (textSize.Height > richTextBox1.Height)
{
    richTextBox1.Text = Document;
    richTextBox1.Update();

    //Number of shown lines
    int FirstCharOfLastShownLine = richTextBox1.GetCharIndexFromPosition(new Point(0, richTextBox1.ClientSize.Height));
    int ShownLines = richTextBox1.GetLineFromCharIndex(FirstCharOfLastShownLine);
    int TotalLines = richTextBox1.GetLineFromCharIndex(richTextBox1.Text.Length - 1);

    for (int p = 0; p < NumberOfPages; p++)
    {
        int FirstLineOfPage = (p * ShownLines);
        int FirstCharOfPage = richTextBox1.GetFirstCharIndexFromLine(FirstLineOfPage);

        int FirstLineOfNextPage = (p + 1) * ShownLines;
        FirstLineOfNextPage = (FirstLineOfNextPage > TotalLines) ? TotalLines : FirstLineOfNextPage;
        int LastCharOfPage = (FirstLineOfNextPage < TotalLines)
                           ? richTextBox1.GetFirstCharIndexFromLine(FirstLineOfNextPage) - 1
                           : richTextBox1.Text.Length;
        Pages.Add(richTextBox1.Text.Substring(FirstCharOfPage, LastCharOfPage - FirstCharOfPage));
    }
}
else
{
    Pages.Add(Document);
}
richTextBox1.Text = Pages.First();