计算打印的最大字符串长度



我正在尝试计算要打印的字符串的最大长度。 我通过使用等宽字体来做到这一点,但它们在页面上占用了太多的水平空间。 我真的需要每行打印更多字符,而不会将字体大小减小到几乎不可见的水平,所以我想改用无衬线字体。 这是我目前的打印功能:

    public static void printPage(ref PrintPageEventArgs e, List<ReportLine> CompanyLetterhead, Queue<ReportLine> reportData)
    {
        int xPosition = e.MarginBounds.X;
        int yPosition = e.MarginBounds.Y;
        int maxCharacters = 0;
        foreach (ReportLine line in CompanyLetterhead)
        {
            maxCharacters = e.MarginBounds.Width / (int)line.selectedFont.Size;
            int position = 0;
            while (line.text.Length - position > maxCharacters)
            {
                e.Graphics.DrawString(line.text.Substring(position, position + maxCharacters), line.selectedFont, Brushes.Black, xPosition, yPosition);
                yPosition += line.selectedFont.Height;
                position += maxCharacters;
            }
            if (line.text.Length - position > 0)
            {
                e.Graphics.DrawString(line.text.Substring(position), line.selectedFont, Brushes.Black, xPosition, yPosition);
                yPosition += line.selectedFont.Height;
            }
        }
        while (reportData.Count > 0 && checkLine(yPosition, e.MarginBounds.Bottom, reportData.Peek().selectedFont.Height))
        {
            ReportLine currentLine = reportData.Peek();
            maxCharacters = e.MarginBounds.Width / (int)currentLine.selectedFont.Size;
            if (currentLine.text.Length > maxCharacters)
            {
                string[] words = currentLine.text.Split(new char[] { ' ' , 't' });
                string printString = "";
                bool endsInSpace = true;
                foreach (string word in words)
                {
                    if (word.Length + printString.Length < maxCharacters)
                    {
                        if (printString.Length > 0)
                        {
                            printString += " ";
                        }
                        printString += word;
                    }
                    else if (printString.Length == 0)
                    {
                        printString += word.Substring(0, maxCharacters);
                        endsInSpace = false;
                    }
                    else
                    {
                        break;
                    }
                }
                e.Graphics.DrawString(printString, currentLine.selectedFont, Brushes.Black, xPosition, yPosition);
                yPosition += currentLine.selectedFont.Height;
                if (endsInSpace)
                {
                    currentLine.text = currentLine.text.Remove(0, printString.Length + 1);
                }
                else
                {
                    currentLine.text = currentLine.text.Remove(0, printString.Length);
                }
            }
            else
            {
                e.Graphics.DrawString(currentLine.text, currentLine.selectedFont, Brushes.Black, xPosition, yPosition);
                yPosition += currentLine.selectedFont.Height;
                reportData.Dequeue();
            }
        }
        e.HasMorePages = reportData.Count > 0;
    }

此函数使用 ReportLine 类对象,这些对象定义如下:

public class ReportLine
{
    public string text;
    public Font selectedFont;
    public ReportLine()
    {
        text = "";
        selectedFont = null;
    }
    public ReportLine(string txt, Font font)
    {
        text = txt;
        selectedFont = font;
    }
}

现在,我如何使用不同字符具有不同宽度的字体来使其工作? 我知道有一个名为 Graphics.MeasureString 的函数,但这只会告诉我所选字体处字符串的总宽度,所以这意味着如果它确实跑过页面边缘,它只会告诉我它会跑多远,而不是会跑多少个字符。

也许你正在寻找Graphics.MeasureCharacterRanges。 您可以通过将字符串拆分为单词来确定要传递给该方法的范围。 这样,您就可以知道每个单词的宽度,可以随心所欲地进行包装。