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();