在处理setInterval
应用程序时,我想将一个长文本(只有字符,没有图像,没有特殊格式)分成多个部分(页面),以便将它们放入{{1} }}。
问题是WinForm
不支持多个页面。
我必须编写自己的算法(某种DP编程)来分割文本。
目前我正在使用RichTextBox
检查字符串是否适合富文本框,例如:
RichTextBox
它不能很好地工作,因为我认为上面的功能不准确。
我想知道是否有一种简单的方法可以做到这一点?感谢。
答案 0 :(得分:1)
我提出的解决问题的方法是将源文档的文本拆分为多个子字符串(Pages),例如每个子字符串都可以放在RichTextBox
客户区域中,而不是产卵/需要滚动条。
因此,第一项任务是计算必须拆分给定文件的Chuncks / Pages的数量。
TextRenderer Class方法是常用的工具
在执行计算时,必须指示类包装文本(如RichTextBox控件所示),排除任何填充并将字符串放入TextBox类型控件编辑区域。
主TextFormatFlags标志将是:
TextFormatFlags.WordBreak | TextFormatFlags.NoPadding | TextFormatFlags.TextBoxControl;
下一个任务是计算RichTextBox控件的客户区域中适合的字母/符号数,以便不需要滚动条。
Winforms
RichTextBox
控件不提供任何特定工具,但非特定工具足以执行此计算。
作为注释,Lines[] property(源自TextBoxBase) 仅报告原始文本行拆分(用作行 (),而不是内部自动换行生成的行。
但是,TextBoxBase GetFirstCharIndexFromLine()和GetLineFromCharIndex()可以组合使用以达到相同的效果:
知道ClientArea中可以容纳多少行,下一行中的第一个字符将比ClientArea中最后一个可见行的最后一个字符多一个字符(空格未被包装)。
然后,只要有足够的行来填充ClientArea,就重复此过程。最后一个 Page 将包含[Total Lines] / [Lines per Page]
。
该程序结果的直观表示:
示例代码,用于执行计算大小和分割源文档文本的基本任务。用于创建示例图像的完整源代码:(PasteBin - RTB Reader)
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();
答案 1 :(得分:0)
我不确定,我没有测试代码,但我希望它可以帮助你,至少会给你一个想法。
将字体大小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行)
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
我们在第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;
}
}
}
并使用|
拆分文字我知道它不健全且教授。解决方案,这只是一个想法......
祝你好日子。