我想从数据网格打印数据。该代码适用于第一页,但注释的行不能很好地运行,不会移动到下一页。任何人都可以帮忙解决这个问题吗?
private void DrawFactorA4(object sender, PrintPageEventArgs ev)
{
for (int j = 0; j < GrdRDocument.Rows.Count; j++)
{
i += 2;
//draw data grid
s++;
if(s == 10)
{
//ev.HasMorePages = true; //this line doesn't work
s = 0;
i = 0;
}
else
{
ev.HasMorePages = false;
}
}
}
_
private void BtnPrint_Click(object sender, EventArgs e)
{
printFont = new Font("Arial", 12);
IEnumerable<PaperSize> paperSizes =
pd.PrinterSettings.PaperSizes.Cast<PaperSize>();
sizeA4 = paperSizes.First<PaperSize>(size => size.Kind == PaperKind.A4);
pd.DefaultPageSettings.Landscape = true;
pd.DefaultPageSettings.PaperSize = sizeA4;
pd.PrintPage += new PrintPageEventHandler(this.DrawFactorA4);
printPreviewDialog.Document = pd;
printPreviewDialog.ShowDialog();
}
答案 0 :(得分:2)
停下来阅读你的内容:
printFont = new Font("Arial", 12);
字体是非托管资源;在这里,你是一个瞬间,永远不会处理它。也许这在这种特殊情况下是无害的,但这是一个习惯性的坏习惯。
pd.PrintPage += new PrintPageEventHandler(this.DrawFactorA4);
将为您文档中的每个页面调用 DrawFactorA4
。在DrawFactorA4
内:
for (int j = 0; j < GrdRDocument.Rows.Count; j++)
您可以遍历Row
中的每个GrdRDocument
,无论行数或页面大小如何。那是错的;你必须在页面填满后停止。顺便说一句,我希望GrdRDocument
是不可变数据的本地副本,并且您没有将UI控件传递给打印线程。
s++;
if(s == 10)
{
//ev.HasMorePages = true; //this line doesn't work
s = 0;
您的评论行可以正常使用。问题是你设置ev.HasMorePages = true
然后忽略它;你设置s = 0
并继续迭代;下一次迭代s!= 10所以你:
ev.HasMorePages = false;
阅读PrintDocument
文档;它有一个打印多个页面的例子。您应该创建一个类来存储所有非托管资源和页面状态。设为IDisposable
以便他们处理掉。仅遍历每个页面上要打印的行或任何内容。类似的东西:
class PrintStuff : IDisposable
{
readonly IEnumerable<Whatever> data;
readonly PrintDocument pd;
Font font;
private int currentIndex;
public PrintStuff(IEnumerable<Whatever> data)
{
this.data = data;
pd = new PrintDocument();
pd.BeginPrint += OnBeginPrint;
pd.PrintPage += OnPrintPage;
pd.EndPrint += OnEndPrint;
}
public void Print()
{
pd.Print();
}
public void Dispose()
{
pd.Dispose();
}
private void OnBeginPrint(object sender, PrintEventArgs args)
{
font = new Font(FontFamily.GenericSansSerif, 12F);
currentIndex = 0;
}
private void OnEndPrint(object sender, PrintEventArgs args)
{
font.Dispose();
}
private void OnPrintPage(object sender, PrintPageEventArgs args)
{
var x = Convert.ToSingle(args.MarginBounds.Left);
var y = Convert.ToSingle(args.MarginBounds.Top);
var lineHeight = font.GetHeight(args.Graphics);
while ((currentIndex < data.Count())
&& (y <= args.MarginBounds.Bottom))
{
args.Graphics.DrawWhatever(data.ElementAt(currentIndex), font, Brushes.Black, x, y);
y += lineHeight;
currentIndex++;
}
args.HasMorePages = currentIndex < data.Count();
}
}