簡體   English   中英

使用 DocumentPaginator 打印時如何打印預覽?

[英]How to Print Preview when using a DocumentPaginator to print?

我正在使用從 DocumentPaginator(見下文)派生的 class 打印來自 WPF 應用程序的簡單(僅文本)報告。 我已經得到它,所以一切都可以正確打印,但是我如何讓它在打印之前進行打印預覽? 我覺得我需要使用 DocumentViewer,但我不知道如何使用。

這是我的分頁器 Class:

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(目前只是一個行列表)。

這是我如何使用我的行分頁器

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 中的 Pro WPF (第 726 頁)后開始工作。

基本上 DocumentViewer class 需要一個 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(命名空間 System.Windows.Xps.Packaging);

這是 PrintPreview Window。

<Window x:Class="WPFPrintTest.PrintPreview"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="previewWindow"
    Title="PrintPreview" Height="800" Width="800">
    <Grid>
        <DocumentViewer Name="viewer" 
                        Document="{Binding ElementName=previewWindow, Path=Document}" />
    </Grid>
</Window>

后面的代碼只有一個 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 中刪除 package。

WPF 沒有任何內置的打印預覽功能,如果您想進行打印預覽,您將不得不自己構建它。 幸運的是,這不應該那么困難。

您已經獲得了創建DocumentPage對象的分頁代碼。 這些對象包含一個Visual ,您可以將其 go 提前並顯示在您的 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();

Where "load" is either a FlowDocument or IDocumentPaginatorSource and here is the 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

希望它適用於您的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM