PrintDocument HasMorePages不起作用

时间:2014-04-08 14:01:55

标签: c# .net printing

我想从数据网格打印数据。该代码适用于第一页,但注释的行不能很好地运行,不会移动到下一页。任何人都可以帮忙解决这个问题吗?

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();
    }

1 个答案:

答案 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();
    }
}