如何在打印之前预先测量字符串?

这是纸质表格的草图 您好,我正在学习使用C#VS 2010 EE进行编程,我正在编写一个应用程序来填充预打印表单。 这个表格在不同的坐标中有几个地方。 纸上的三个盒子是多行5“W x 2”H盒子。

我已经为纸质表单上的每个位置创建了一个带有一个TextBox的窗体。

问题是当在这些多行文本框中输入信息时,我需要知道在纸上留下多少行以输入更多文本,以及何时停止输入,因为PrePrinted框中没有更多可用空间。

我做了很多搜索,但我发现的一切都是关于在屏幕上进行测量,这与纸张上的最终结果不符。

换句话说,我需要知道如何在输入TextBoxes时找出纸张上的字符串尺寸,并将其与PrePrinted表单上的可用空间进行比较,这样我就可以在它经过之前停止在纸上的框的底部边框。

纸上的第一个盒子的高度为5英寸,宽度为2英寸,从“ new RectangleF(60.0F, 200.0F, 560.0F, 200.0F) ”开始。 我明白这些数字是百分之一英寸。

所有这一切,考虑到我不能通过字符数限制TextBoxes,因为并非所有字符占据相同的空间,如H != I; M != l; 等等

预先感谢您的帮助。 今天是2011年9月5日,基于您的意见和建议,我已将代码更改为使用Graphics.MeasureString。

这是我现在使用Graphics.MeasureString和只有一个richTextBox的代码:从printDocument1_PrintPage事件中完美运行, 但我不知道如何使它从richTextBox1_TextChanged事件中运行

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Printing;//Needed for the PrintDocument() using System.Linq; using System.Text; using System.Windows.Forms; namespace Printing { public partial class Form1 : Form { private Font printFont1; string strPrintText; public Form1() { InitializeComponent(); } private void cmdPrint_Click(object sender, EventArgs e) { try { PrintDocument pdocument = new PrintDocument(); pdocument.PrintPage += new PrintPageEventHandler (this.printDocument1_PrintPage); pdocument.Print(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } public void printDocument1_PrintPage (object sender, System.Drawing.Printing.PrintPageEventArgs e) { strPrintText = richTextBox1.Text.ToString(); printFont1 = new Font("Times New Roman", 10); //I had to remove this line from the btnPrintAnexo1_Click Graphics g = e.Graphics; StringFormat format1 = new StringFormat(); RectangleF rectfText; int iCharactersFitted, iLinesFitted; rectfText = new RectangleF(60.0F, 200.0F, 560.0F, 200.0F); // The following e.Graphics.DrawRectangle is // just for debuging with printpreview e.Graphics.DrawRectangle(new Pen(Color.Black, 1F), rectfText.X, rectfText.Y, rectfText.Width, rectfText.Height); format1.Trimming = StringTrimming.Word; //Word wrapping //The next line of code "StringFormatFlags.LineLimit" was commented so the condition "iLinesFitted > 12" could be taken into account by the MessageBox // Use next line of code if you don't want to show last line, which will be clipped, in rectangleF //format1.FormatFlags = StringFormatFlags.LineLimit; //Don't use this next line of code. Some how it gave me a wrong linesFilled //g.MeasureString(strPrintText, font, rectfFull.Size, //StringFormat.GenericTypographic, out iCharactersFitted, out iLinesFilled); //Use this one instead: //Here is where we get the quantity of characters and lines used g.MeasureString(strPrintText, printFont1, rectfText.Size, format1, out iCharactersFitted, out iLinesFitted); if (strPrintText.Length == 0) { e.Cancel = true; return; } if (iLinesFitted > 12) { MessageBox.Show("Too many lines in richTextBox1.\nPlease reduce text entered."); e.Cancel = true; return; } g.DrawString(strPrintText, printFont1, Brushes.Black, rectfText, format1); g.DrawString("iLinesFilled = Lines in the rectangle: " + iLinesFitted.ToString(), printFont1, Brushes.Black, rectfText.X, rectfText.Height + rectfText.Y); g.DrawString("iCharactersFitted = Characters in the rectangle: " + iCharactersFitted.ToString(), printFont1, Brushes.Black, rectfText.X, rectfText.Height + rectfText.Y + printFont1.Height); } private void richTextBox1_TextChanged(object sender, EventArgs e) { //***I don't know what to type here.***  if (iLinesFitted == 13) { MessageBox.Show("Too many lines in richTextBox1.\nPlease erase some characters."); } } private void cmdPrintPreview_Click(object sender, EventArgs e) { printPreviewDialog1.ShowDialog(); } private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e) { // strPrintText = richTextBox1.Text; } } } 

我认为这就是你所追求的。

MeasureString(…)

Juat确保您的图形对象是PrintDocument。

 using System; using System.Drawing; using System.Drawing.Printing; using System.Windows.Forms; namespace GraphicsHandler { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void textBox1_TextChanged(object sender, EventArgs e) { // Check the width of the text whenever it is changed. if (checkTextWillFit(textBox1.Text) == true) { MessageBox.Show("Entered test is too wide, please reduce the number of characters."); } } private bool checkTextWillFit(string enteredText) { // Create a handle to the graphics property of the PrintPage object Graphics g = pd.PrinterSettings.CreateMeasurementGraphics(); // Set up a font to be used in the measurement Font myFont = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Millimeter); // Measure the size of the string using the selected font // Return true if it is too large if (g.MeasureString(enteredText, myFont).Width > 100) { return true; } else { return false; } } PrintDocument pd = null; private void Form1_Load(object sender, EventArgs e) { // Initialise the print documnet used to render the printed page pd = new PrintDocument(); // Create the event handler for when the page is printed pd.PrintPage += new PrintPageEventHandler(pd_PrintPage); } void pd_PrintPage(object sender, PrintPageEventArgs e) { // Page printing logic here } } } 

文本框中的信息将存储在数据库中,并在一段时间内打印在预打印表单上。 由于纸张上每个盒子的空间有限,我必须确保进入数据库的内容不超过纸质表格中每个单元格可以处理的内容。 这是避免用户输入的行数超出了矩形F的代码:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Printing;//Needed for the PrintDocument() using System.Linq; using System.Text; using System.Windows.Forms; namespace Printing { public partial class Form1 : Form { private Font printFont1; string strPrintText; public Form1() { InitializeComponent(); } //PrintDocument printDocument1 = null; In ny case it makes this error: 'Printing.Form1' already contains a definition for 'primtDocument1' private void Form1_Load(object sender, EventArgs eP) { PrintDocument pd = new PrintDocument(); pd.PrintPage += new PrintPageEventHandler (this.printDocument1_PrintPage); } private void richTextBox1_TextChanged(object sender, EventArgs e) { // Check the width of the text whenever it is changed. if (checkTextWillFit(richTextBox1.Text) == true) { MessageBox.Show("\nEntered text pruduces too many lines. \n\nPlease reduce the number of characters.", "Too Many Lines"); } } private bool checkTextWillFit(string enteredText) { StringFormat format1 = new StringFormat(); format1.Trimming = StringTrimming.Word; //Word wrapping RectangleF rectfText; int iCharactersFitted, iLinesFitted; rectfText = new RectangleF(60.0F, 200.0F, 560.0F, 200.0F); // Create a handle to the graphics property of the PrintPage object Graphics g = printDocument1.PrinterSettings.CreateMeasurementGraphics(); // Set up a font to be used in the measurement Font myFont = new Font("Times New Roman", 10, FontStyle.Regular); // Measure the size of the string using the selected font // Return true if it is too large g.MeasureString(enteredText, myFont, rectfText.Size, format1, out iCharactersFitted, out iLinesFitted); if (iLinesFitted > 12) { return true; } else { return false; } } private void cmdPrint_Click(object sender, EventArgs e) { try { PrintDocument pdocument = new PrintDocument(); pdocument.PrintPage += new PrintPageEventHandler (this.printDocument1_PrintPage); pdocument.Print(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } public void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { strPrintText = richTextBox1.Text.ToString(); printFont1 = new Font("Times New Roman", 10); //I had to remove this line fromthe btnPrintAnexo1_Click Graphics g = e.Graphics; //float cyFont = printFont1.GetHeight(g); StringFormat format1 = new StringFormat(); format1.Trimming = StringTrimming.Word; //Word wrapping RectangleF rectfText; int iCharactersFitted, iLinesFitted; rectfText = new RectangleF(60.0F, 200.0F, 560.0F, 200.0F); // The following e.Graphics.DrawRectangle is // just for debuging with printpreview e.Graphics.DrawRectangle(new Pen(Color.Black, 1F), rectfText.X, rectfText.Y, rectfText.Width, rectfText.Height); //Here is where we get the quantity of characters and lines used g.MeasureString(strPrintText, printFont1, rectfText.Size, format1, out iCharactersFitted, out iLinesFitted); if (strPrintText.Length == 0) { e.Cancel = true; return; } if (iLinesFitted > 12) { MessageBox.Show("Too many lines in richTextBox1.\nPlease reduce text entered."); e.Cancel = true; return; } g.DrawString(strPrintText, printFont1, Brushes.Black, rectfText, format1); g.DrawString("iLinesFilled = Lines in the rectangle: " + iLinesFitted.ToString(), printFont1, Brushes.Black, rectfText.X, rectfText.Height + rectfText.Y); g.DrawString("iCharactersFitted = Characters in the rectangle: " + iCharactersFitted.ToString(), printFont1, Brushes.Black, rectfText.X, rectfText.Height + rectfText.Y + printFont1.Height); } private void cmdPrintPreview_Click(object sender, EventArgs e) { printPreviewDialog1.ShowDialog(); } private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e) { // strPrintText = richTextBox1.Text; } } } 

如果我是对的,你可以在打印之前使用一个名为FormattedText的类来格式化它。 然后,您可以检查FormatedText的width属性。

这里有一个很好的打印教程: http : //www.switchonthecode.com/tutorials/printing-in-wpf 。 第二部分更侧重于分页(这是我认为你正在处理的): http : //www.switchonthecode.com/tutorials/wpf-printing-part-2-pagination 。 FormattedText出现在此处。