首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用DocumentPaginator打印时如何打印预览?

使用DocumentPaginator打印时如何打印预览?
EN

Stack Overflow用户
提问于 2009-02-25 02:57:16
回答 6查看 33.6K关注 0票数 19

我使用从DocumentPaginator派生的类(参见下面)来打印来自WPF应用程序的简单(仅文本)报告。我得到了它,这样所有的东西都能正确地打印,,但是我如何让它在打印之前进行打印预览呢?,我有一种感觉,我需要使用DocumentViewer,但我不知道如何使用。

这是我的分页器课程:

代码语言:javascript
复制
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,它显示数据(目前只是一个行列表)。

下面是我如何使用我的行分页器

代码语言:javascript
复制
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");
}

对不起,代码转储,但我不想错过一些相关的东西。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-02-25 21:31:08

因此,我在阅读了2008年C#中的Pro WPF (第726页)之后,让它开始工作。

基本上,DocumentViewer类需要一个XPS文件来显示它的打印预览。因此,我做以下几点:

代码语言:javascript
复制
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 (NamespaceSystem.Windows.Xps.Packaging);

这是PrintPreview窗口。

代码语言:javascript
复制
<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>

后面的代码只有如下的文档属性:

代码语言:javascript
复制
public IDocumentPaginatorSource Document
{
    get { return viewer.Document; }
    set { viewer.Document = value; }
}
票数 21
EN

Stack Overflow用户

发布于 2011-01-05 07:39:45

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

代码语言:javascript
复制
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中删除包。

票数 6
EN

Stack Overflow用户

发布于 2009-02-25 17:41:07

WPF不附带任何内置的打印预览功能,如果您想要进行打印预览,您必须自己构建它。幸运的是,这不应该那么困难。

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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/584551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档