C# 为什么Windows窗体中的多页打印会以这种方式工作?

C# 为什么Windows窗体中的多页打印会以这种方式工作?,c#,winforms,printing,C#,Winforms,Printing,由于我们最近学习了如何在Windows窗体中打印,我想知道为什么要打印多页,OnPrintPage(PrintPageEventArgs e)您的PrintDocument的每个页面都会被调用,并告诉它我有多页,我必须将e.HasMorePages设置为true。我想到了多种其他解决方案,比如可以绘制的Page对象和返回这些对象数组的OnPrintPage方法 但由于我认为微软有很好的理由按照他们的方式实现它,我想知道是否有人知道API看起来如此的原因。它只是从根本上映射到Windows上的打印

由于我们最近学习了如何在Windows窗体中打印,我想知道为什么要打印多页,
OnPrintPage(PrintPageEventArgs e)
您的
PrintDocument
的每个页面都会被调用,并告诉它我有多页,我必须将
e.HasMorePages
设置为true。我想到了多种其他解决方案,比如可以绘制的
Page
对象和返回这些对象数组的
OnPrintPage
方法


但由于我认为微软有很好的理由按照他们的方式实现它,我想知道是否有人知道API看起来如此的原因。

它只是从根本上映射到Windows上的打印工作方式。它是基于页面的,打印机驱动程序一次只能处理一页。StartDoc和EndDoc是外部winapi函数,用于选择驱动程序并将其关闭。它们映射到PrintDocument.BeginPrint和EndPrint事件

然后,应用程序必须在开始将图形渲染到打印机的设备上下文之前调用StartPage winapi函数。它映射到PrintPage事件,PrintController在调用StartPage后立即启动它。当应用程序渲染完页面后,必须调用EndPage。PrintPage事件处理程序返回时由PrintController完成。这会在后台处理程序中添加一个页面

设置e.MorePages=true只是告诉PrintController它需要留在循环中,再次调用StartPage并触发PrintPage事件


这会使打印有点痛苦,您必须在PrintPage事件调用之间维护自己的状态。必须将它们存储在类内的字段中,它们不能是PrintPage事件处理程序的局部变量。我已经为PrintDocument编写了一个函数替换,它没有这个问题,您可以用一个方法呈现整个文档。使用分隔页面的FormFeed()方法。你可以在这里找到代码。还要注意,C#迭代器(yield return语句)是如何很好地解决该问题的通用解决方案。

“…OnPrintPage方法返回这些对象的数组”-这会增加您对超大文档的内存需求。@Joe这可能是真的,但它当前的工作方式不需要存储页面吗?如果Windows API看起来像这样,那么以这种方式实现它是有意义的。我很高兴你能对这个话题有所了解。