C# 如何在打印前预先测量字符串?
你好,我正在学习C#VS 2010 EE编程,我正在申请填写一份预打印的表格。此表单在不同坐标中有多个位置。纸上的三个盒子是多行5英寸宽x 2英寸高的盒子 我已经用一个C# 如何在打印前预先测量字符串?,c#,string,printing,measure,C#,String,Printing,Measure,你好,我正在学习C#VS 2010 EE编程,我正在申请填写一份预打印的表格。此表单在不同坐标中有多个位置。纸上的三个盒子是多行5英寸宽x 2英寸高的盒子 我已经用一个文本框为纸质表单上的每个位置创建了windows表单 问题是,当在这些多行文本框中输入信息时,我需要知道纸张上还有多少行可以输入更多文本,以及何时停止输入,因为预打印框中没有更多可用空间 我做了很多搜索,但我发现的一切都是关于在屏幕上测量的,这与纸上的最终结果不匹配 换句话说,我需要知道如何在输入文本框时找出纸上的字符串尺寸,并将
文本框
为纸质表单上的每个位置创建了windows表单
问题是,当在这些多行文本框中输入信息时,我需要知道纸张上还有多少行可以输入更多文本,以及何时停止输入,因为预打印框中没有更多可用空间
我做了很多搜索,但我发现的一切都是关于在屏幕上测量的,这与纸上的最终结果不匹配
换句话说,我需要知道如何在输入文本框时找出纸上的字符串尺寸,并将其与预打印表单上的可用空间进行比较,以便在它越过纸上框的底部边界之前停止
纸张上的第一个框宽5英寸,高2英寸,从“新矩形F(60.0F、200.0F、560.0F、200.0F)
”开始。我知道这些数字是百分之一英寸
所有这些,考虑到我不能按字符数量限制文本框,因为并非所有字符都占用相同的空间,如H!=一,代码>M!=l代码>等
提前感谢您的帮助。
今天是2011年9月5日,根据您的评论和建议,我已将代码更改为使用Graphics.MeasureString
这是我现在使用Graphics.MeasureString和一个richTextBox的代码:
在printDocument1\u PrintPage事件中工作正常,但我不知道如何在richTextBox1\u TextChanged事件中工作
如果我是对的,您可以在打印之前使用名为FormattedText的类对其进行格式化。然后可以检查FormattedText的width属性
这里有一个关于打印的好教程:。第二部分更侧重于分页(我认为您正在处理这个问题):。格式化文本出现在这里。我想这就是你想要的
请确保图形对象是打印文档
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;
}
}
}
您尝试过使用吗?这不会很好地工作,Winforms不会进行分辨率无关的文本呈现。TrueType提示将是你的报应,使屏幕上的文本与打印机上的文本略有不同。这会在换行时产生很大的差异。考虑WPF或Adobe产品。根据您的意见和建议,我已经更改了使用GraceC.StultScript的代码。在printDocument1_PrintPage事件中工作正常,但我不知道如何在richTextBox1_TextChanged事件中工作,这样我就可以用消息框阻止用户并让他们删除richTextBox中的一些文本@Hans Passant,这不可能基于我的评论:)一定要避免用消息框向用户发送垃圾邮件。只需简单地不在显示器上显示文本,就可以清楚地表明文本不会被打印出来。请检查以下答案,以了解MeasureString()的作用示例:大家好,谢谢大家的评论。我刚刚上传了一张图片;这是我想用这份申请表填写的纸质表格的草图。打印一次只打印一页,而且,并不是所有的框都将被使用。我将尝试你的建议,但我甚至不知道如何实施它们。如果你能给我更多的信息,我将不胜感激。多谢各位@Jalal Aldeen Saa’d基于所有评论和建议,我已将代码更改为使用Graphics.MeasureString。现在可以从printDocument1_PrintPage事件中完美地工作,但是我需要,并且不知道如何从richTextBox1_TextChanged事件中工作,这样我就可以使用MessageBox阻止用户并让他们删除richTextBox中的一些文本。我对编程非常陌生;也许你或者其他人可以帮我。提前感谢您的时间。@tinchouHello@Jason James,您的代码“帮了我很多”。我根据我的应用程序调整了它,现在正在工作,它正做着我想做的事情。我将发布我到现在为止的代码,它工作得很好。正如Hans前几天建议我的那样,最终的代码将避免使用MessageBox,我想我会添加一个隐藏的标签,用大而粗体的闪光的红色字母代替:D。如果你们有更多的建议,请告诉我。非常感谢。您好@tinchou,谢谢您的评论。我刚刚上传了一张图片;这是我想用这份申请表填写的纸质表格的草图。打印一次只打印一页,而且,并不是所有的框都将被使用。我来看看这个链接。问题是我没有使用WPF,我使用的是Windows窗体应用程序。你认为这很重要还是没有区别?谢谢。不幸的是,是的,用WPF和WinForms打印是完全不同的。几乎所有WPF的元素都是可视的,这是基于矢量的图形,可以轻松打印。我从未在WinForms中进行过打印,但我找到了一个指向msdn的链接,其中包含有关WPF的FormattedText和WinForms的DrawText相似性的信息。希望帮助您也可以查看DrawText文档,它可能会为您提供一种测量格式化文本的简单方法
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;
}
}
}