我需要打印绑定到WPF中的数据的控件,我将有一个用户控件,它将具有绑定到数据的Grid等控件,并且我想打印用户控件。我还需要支持分页,页眉和页脚以及插入自定义徽标。
是否有任何文章/示例代码可以帮助我入门。
答案 0 :(得分:3)
虽然向打印机发送视觉效果非常简单,但如果您需要处理分页,缩放,页眉和页脚,则可以更多地参与其中。但即使这并不是那么困难,您可以通过编写用户xaml用户控件来生成打印输出。我喜欢这个printing overview on MSDN来了解工作流程的一般情况。
要进行分页,您需要创建一个继承自System.Windows.Documents.DocumentPaginator的类。此类允许您告诉打印机要打印的页面以及每页上的项目排列方式。
在paginator中,您将通过实例化要打印的用户控件以编程方式构建页面。如果需要页眉/页脚,则为这些创建用户控件,实例化它们,设置任何所需的DataContext属性,并将它们添加到页面中。在大多数情况下,您可以以编程方式创建类似Grid的内容,配置列/行,向其添加用户控件,然后将其作为可视化返回。
一个技巧......你可能需要强制布局系统来布局控件。当您在屏幕上显示时会自动完成此操作,但如果您手动创建,则需要自己执行此操作:
var pageSize = new Size(8.5 * 96.0, 11.0 * 96.0);
var pageRect = new Rect(new Point(0, 0), pageSize);
...
// create root visual (like a grid) and add user controls
...
root.Measure(pageSize);
root.Arrange(pageRect);
root.InvalidateVisual();
root.UpdateLayout();
DocumentPaginator上的文档很好地解释了如何使用该类。但是对于分页数据的情况,您可能需要自己做。我通常会确定页面的大小以及该页面上可以容纳的行数。然后我以编程方式将数据拆分成多个集合。也许每个系列中有25个项目。然后我将一组绑定到每个页面的列表/网格。
最后,你需要将它送到打印机。这大致是我用来创建XPS文档并将其发送到打印机的内容。并且...您可以使用此变体轻松显示打印预览对话框。只需创建一个对话框,其中包含一个显示XPS文档的FixedDocumentViewer。
public static string Print(DocumentPaginator paginator, string printQueueName, string documentName)
{
using (MemoryStream xpsStream = new MemoryStream())
{
using (Package package = Package.Open(xpsStream, FileMode.Create, FileAccess.ReadWrite))
{
string packageUriString = "memorystream://data.xps";
Uri packageUri = new Uri(packageUriString);
try
{
PackageStore.AddPackage(packageUri, package);
using (XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.Maximum, packageUriString))
{
PrintTicket printTicket = new PrintTicket();
printTicket.PageMediaSize = new PageMediaSize(paginator.PageSize.Width, paginator.PageSize.Height);
var writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
writer.Write(paginator, printTicket);
FixedDocumentSequence document = xpsDocument.GetFixedDocumentSequence();
xpsDocument.Close();
PrintQueue targetQueue = null;
// Get the queue.
if (!string.IsNullOrEmpty(printQueueName))
{
var printServer = new LocalPrintServer();
targetQueue = printServer.GetPrintQueue(printQueueName);
}
// If no queue, then ask the user for a queue.
if (null == targetQueue)
{
var printDialog = new PrintDialog();
printDialog.PrintTicket = printTicket;
printDialog.UserPageRangeEnabled = false;
var response = printDialog.ShowDialog();
if (response.GetValueOrDefault() && null != printDialog.PrintQueue)
{
targetQueue = printDialog.PrintQueue;
}
else
{
return null;
}
}
var targetQueueWriter = PrintQueue.CreateXpsDocumentWriter(targetQueue);
document.Name = documentName;
targetQueueWriter.Write(document);
return document.Name;
}
}
finally
{
PackageStore.RemovePackage(packageUri);
}
}
}
}