Why isn't the PrintPreview exactly the same as the paper print?
Okay, before you spam me with StringFormat.Alignment = StringAlignment.Center ... hear my whole issue:
When I draw text with the following code, the string is centered in the PrintPreview, but NOT CENTERED on the actual paper when it prints. The whole page is off to the right just a little, thus some stuff shows as printing on the print preview, but falls off the paper (not just outside the margin range, but OFF the paper) when printed.
private void button1_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
PrintPreviewDialog ppd = new PrintPreviewDialog();
((Form)ppd).WindowState = FormWindowState.Maximized;
ppd.Document = pd;
ppd.ShowDialog();
}
void pd_PrintPage(object sender, PrintPageEventArgs e)
{
for (int y = 100; y < 400; y += 25)
{
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(5, y, 84开发者_运维问答0, 25));
}
e.HasMorePages = false;
}
Any thoughts as to why it's off? This should be trivial, but it isn't.
EDIT: I've found that it's not just text... It's printing EVERYTHING off just a little. I've updated the code above to provide a better example of the issue. Just drop this in a form with a button on it.
EDIT 2: With the answer given, I've modified the code and this now works. I'm providing the final code for those that may want to see it. I have to recognize whether i'm seeing this in the PrintPreview dialog or on paper, so I have a IsPreview flag to handle this.
public partial class Form1 : Form
{
bool IsPreview = true;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IsPreview = true;
PrintDocument pd = new PrintDocument();
pd.EndPrint += new PrintEventHandler(pd_EndPrint);
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
PrintPreviewDialog ppd = new PrintPreviewDialog();
((Form)ppd).WindowState = FormWindowState.Maximized;
ppd.Document = pd;
ppd.ShowDialog();
}
void pd_EndPrint(object sender, PrintEventArgs e)
{
IsPreview = false;
}
void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Rectangle b3 = e.PageBounds;
if (IsPreview)
{
e.Graphics.TranslateTransform(e.PageSettings.HardMarginX, e.PageSettings.HardMarginY);
}
b3.Width -= (int)e.PageSettings.HardMarginX * 2;
b3.Height -= (int)e.PageSettings.HardMarginY * 3;
int y = b3.Y;
int x=0;
while ((y + 25) < b3.Bottom)
{
x++;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
Rectangle R = new Rectangle(b3.X, y, b3.Width, 25);
e.Graphics.DrawRectangle(Pens.Black, R);
e.Graphics.DrawString(x.ToString(), this.Font, Brushes.Black, b3.X + 5, y + 5);
y += 25;
}
// draw the last little bit
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(b3.X, y, b3.Width, b3.Height - y));
e.HasMorePages = false;
}
}
Being off towards the right tends to be explainable by the value of the PageSettings.HardMarginX
property. A value produced by the printer driver. Printer drivers are however typically not very good at guessing what the actual paper route through the printer might look like. That's mechanical, pinch rollers, tray alignment and whatnot. Software and Mechanical engineers don't have lunch together often enough.
But a software engineer can almost always fix a mechanical engineer's problem. You'll need an Options dialog to allow the user to fix the mechanical engineer's problem. Use the value in e.Graphics.TranslateTransform
call.
The reason the preview doesn't match up to the paper is because you haven't selected a printer yet. Every printer is a bit different for things like unprintable areas, forced margins, etc. It's been a while since I've done winforms printing, but I do recall that the passed graphics object has a way to account for that.
精彩评论