使用DocumentPaginator进行打印时如何打印预览?

我正在使用我从DocumentPaginator派生的类(见下文)来打印来自WPF应用程序的简单(仅文本)报告。 我已经准备好了所有内容都能正确打印, 但是如何让它在打印之前进行打印预览呢? 我有一种感觉,我需要使用DocumentViewer,但我无法弄清楚如何。

这是我的Paginator类:

public class RowPaginator : DocumentPaginator { private int rows; private Size pageSize; private int rowsPerPage; public RowPaginator(int rows) { this.rows = rows; } public override DocumentPage GetPage(int pageNumber) { int currentRow = rowsPerPage * pageNumber; int rowsToPrint = Math.Min(rowsPerPage, rows - (rowsPerPage * pageNumber - 1)); var page = new PageElementRenderer(pageNumber + 1, PageCount, currentRow, rowsToPrint) { Width = PageSize.Width, Height = PageSize.Height }; page.Measure(PageSize); page.Arrange(new Rect(new Point(0, 0), PageSize)); return new DocumentPage(page); } public override bool IsPageCountValid { get { return true; } } public override int PageCount { get { return (int)Math.Ceiling(this.rows / (double)this.rowsPerPage); } } public override Size PageSize { get { return this.pageSize; } set { this.pageSize = value; this.rowsPerPage = PageElementRenderer.RowsPerPage(this.pageSize.Height); if (rowsPerPage <= 0) throw new InvalidOperationException("Page can't fit any rows!"); } } public override IDocumentPaginatorSource Source { get { return null; } } } 

PageElementRenderer只是一个显示数据的简单UserControl(目前只是一个行列表)。

这是我使用Row Paginator的方式

 PrintDialog dialog = new PrintDialog(); if (dialog.ShowDialog() == true) { var paginator = new RowPaginator(rowsToPrint) { PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight) }; dialog.PrintDocument(paginator, "Rows Document"); } 

很抱歉代码转储,但我不想错过相关的东西。

所以我在C#2008 (页726)中阅读Pro WPF之后就开始工作了。

基本上,DocumentViewer类需要一个XPS文件来呈现它的打印预览。 所以我做了以下事情:

 PrintDialog dialog = new PrintDialog(); var paginator = new RowPaginator(rowsToPrint) { PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight) }; string tempFileName = System.IO.Path.GetTempFileName(); //GetTempFileName creates a file, the XpsDocument throws an exception if the file already //exists, so delete it. Possible race condition if someone else calls GetTempFileName File.Delete(tempFileName); using (XpsDocument xpsDocument = new XpsDocument(tempFileName, FileAccess.ReadWrite)) { XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument); writer.Write(paginator); PrintPreview previewWindow = new PrintPreview { Owner = this, Document = xpsDocument.GetFixedDocumentSequence() }; previewWindow.ShowDialog(); } 

我正在创建打印对话框以获取默认页面大小。 可能有更好的方法来做到这一点。 XpsDocument位于ReachFramework.dll(Namespace System.Windows.Xps.Packaging)中;

这是PrintPreview窗口。

      

后面的代码只有一个Document属性,如下所示:

 public IDocumentPaginatorSource Document { get { return viewer.Document; } set { viewer.Document = value; } } 

以下代码使用MemoryStream进行打印预览。

 MemoryStream stream = new MemoryStream(); Package package = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite); var uri = new Uri(@"memorystream://myXps.xps"); PackageStore.AddPackage(uri, package); var xpsDoc = new XpsDocument(package); xpsDoc.Uri = uri; XpsDocument.CreateXpsDocumentWriter(xpsDoc).Write(paginator); documentViewer.Document = xpsDoc.GetFixedDocumentSequence(); 

记得在关闭打印预览时使用close()并从PackageStore中删除包。

WPF没有任何内置的打印预览function,如果你想进行打印预览,你将不得不自己构建它。 幸运的是,它不应该那么困难。

您已经获得了分页代码,它会创建您的DocumentPage对象。 这些对象包含一个Visual ,您可以继续在UI中显示。

你最终要做的是,对整个文档进行分页,收集所有的DocumentPage对象,然后在滚动的StackPanel或类似内容中显示它们的视觉效果。 这些是您可以发送到打印机的相同DocumentPage对象。

用于打印预览的WinForm代码是:

 PrintPreviewDialog PrintPreviewDialog = new PrintPreviewDialog(); PrintPreviewDialog.Document = PrintDocument; PrintPreviewDialog.ShowDialog(); 

Ps:原始海报评论说这是WPF应用程序的错误答案。

 XpsDocument doc = new XpsDocument("filename.xps", FileAccess.Read); docViewer.Document = doc.GetFixedDocumentSequence(); doc.Close(); 

我不认为有这样做的内置方式

以下是我在NHaml工作的方式

 var documentViewHostDialog = new DocumentDialog(); documentViewHostDialog.LoadDocument(load); documentViewHostDialog.ShowDialog(); 

其中“load”是FlowDocument或IDocumentPaginatorSource,这里是DocumentDialog http://code.google.com/p/nhaml/source/browse/trunk/src/NHaml.Xps/DocumentDialog.xaml http:// code。 google.com/p/nhaml/source/browse/trunk/src/NHaml.Xps/DocumentDialog.xaml.cs

希望它适用于您的情况。