c# - XpsDocument 忽略我的高度设置

标签 c# wpf printing preview xpsdocument

当我尝试在 XPS 文档上声明 PageHeight 时遇到问题。

到目前为止,我的代码如下所示:

private FixedDocumentSequence GetDocument(DocumentPaginator paginator)
{
    FixedDocumentSequence document = null;

    string tempFileName = System.IO.Path.GetTempFileName();
    File.Delete(tempFileName);

    using (var xpsDocument = new XpsDocument(tempFileName, FileAccess.ReadWrite, CompressionOption.NotCompressed))
    {
        var writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);

        var printTicket = new PrintTicket
        {
            PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA4, paginator.PageSize.Width, paginator.PageSize.Height),
            PageBorderless = PageBorderless.Borderless,
            PageMediaType = PageMediaType.None,
        };

        writer.Write(paginator, printTicket);

        //paginator.PageSize.Height = 1122
        var d = xpsDocument.GetFixedDocumentSequence();

        //d.DocumentPaginator.PageSize.Height = 1056
        document = d;
    }

    return document;
}

问题是我声明的 PageSize 高度为 1122,这是我从这段代码中得到的:

var pd = new PrintDialog();
var sz = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);

但是当我查看特性时

d.DocumentPaginator.PageSize.Height

我可以看到高度是 1056,这个高度恰好是 NorthAmericanLetter Page 格式高度的高度,我已经指定了一个具有显式 PageMediaSize 的特定 printTicket 还有什么可能是错误的?

编辑:

这是我编辑过的代码,但这给出了相同的结果:

private FixedDocumentSequence GetDocument(DocumentPaginator paginator)
{
    FixedDocumentSequence document = null;

    string oldTempFileName = System.IO.Path.GetTempFileName();
    File.Delete(oldTempFileName);

    XpsDocument oldXpsDocument;
    using (oldXpsDocument = new XpsDocument(oldTempFileName, FileAccess.ReadWrite, CompressionOption.NotCompressed))
    {
        var writer = XpsDocument.CreateXpsDocumentWriter(oldXpsDocument);

        var printTicket = new PrintTicket
        {
            PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA4, paginator.PageSize.Width, paginator.PageSize.Height),
            PageBorderless = PageBorderless.Borderless,
            PageMediaType = PageMediaType.None,
        };

        writer.Write(paginator, printTicket);
    }

    //string newTempFileName = System.IO.Path.GetTempFileName();
    //File.Delete(newTempFileName);

    using (var newXpsDocument = new XpsDocument(oldTempFileName, FileAccess.Read, CompressionOption.NotCompressed))
    {
        var d = newXpsDocument.GetFixedDocumentSequence();
        document = d;
    }


    return document;
}

我查看了使用第一个 using block 创建的文件,我仍然可以看到页面的高度为 1056,1.fpage 文件的输出:

<FixedPage 
xmlns="http://schemas.microsoft.com/xps/2005/06" xmlns:x="http://schemas.microsoft.com/xps/2005/06/resourcedictionary-key"
xml:lang="und" 
Width="816" Height="1056">
<FixedPage.Resources>
<ResourceDictionary>
<LinearGradientBrush x:Key="b0" StartPoint="33,0" EndPoint="33,23" ColorInterpolationMode="SRgbLinearInterpolation" MappingMode="Absolute" SpreadMethod="Pad">

编辑2:

找到了解决我的问题的方法。 在我的 DocumentPaginator 中,我必须重写 GetPage 方法并在那里返回一个新的 DocumentPage(视觉),此构造函数有一个重载,只有当我在那里正确设置 PageSizes 时才允许我设置 PageSize。

http://msdn.microsoft.com/en-us/library/system.windows.documents.documentpage(v=vs.110).aspx http://msdn.microsoft.com/en-us/library/ms597306(v=vs.110).aspx

我以前的代码:

public override DocumentPage GetPage(int pageNumber)
{
    // create page element (PageTemplate is a custom usercontrol that can hold content)
    var page = new PageTemplate(this, pageNumber + 1);

    // arrange the elements on the page
    page.Arrange(new Rect(0, 0, PageSize.Width, PageSize.Height));

    // return new document page
    return new DocumentPage(page);
}

现在有了第二个构造函数:

public override DocumentPage GetPage(int pageNumber)
{
    // create page element (PageTemplate is a custom usercontrol that can hold content)
    var page = new PageTemplate(this, pageNumber + 1);

    // arrange the elements on the page
    page.Arrange(new Rect(0, 0, PageSize.Width, PageSize.Height));

    // return new document page
    return new DocumentPage(page, PageSize, new Rect(0, 0, 10, 10), new Rect());
}

最佳答案

问题是您希望 xpsDocument 具有与您创建的文件相同的尺寸。

当您创建一个 XpsDocument 时,它会有一个默认的 FixedDocumentSequence。由于您创建的是 XpsDocument,而不是打开 XpsDocument,因此您将获得默认的固定文档序列,这就是为什么您看到 1056 作为高度的原因——default 是默认值。

但是,如果您查看 FixedDocumentSequence 底部的代码示例,您会看到 LoadDocumentViewer,它将旧的 XpsDocument 替换为新的。

当您调用 writer.Write(paginator, printTicket); 时,它将使用 PrintTicket 向您指定的文件写入一个 XpsDocument假如。现在您需要使用该文件路径创建一个 XpsDocument,当您打开它时,您可以获取该文档的 FixedDocumentSequence 以及与 匹配的大小PrintTicket 属性。所以在伪代码中,你应该这样做:

string fileName = ...
using Create XpsDocument at fileName 
    Create XpsDocumentWriter
    Create and setup PrintTicket
    Write to the file using your DocumentPaginator and PrintTicket
using Create XpsDocument reading from fileName
    document = opened XpsDocument GetFixedDocumentSequence()

编辑:

在您上次编辑中找到了很好的结果。我使用 A4 大小设置使用 MS Word 打印了一个 XPS 文档,所有页面也显示为 1056 x 816。然后,我使用 A3 大小创建了一个 XPS 文档,大小为 1587.36 x 1122.56。显然内部发生了一些我们看不到的事情;我的猜测是,由于页面大小在维度上相似,它只使用 1056 x 816 维度?谁知道呢……我建议向 Microsoft 提交错误报告。

与此同时,也许可以尝试更改 d.DocumentPaginator.PageSize 甚至 d.PrintTicket 对象并尝试让页面大小以这种方式进行更改。如果有办法枚举 FixedPage,您也可以手动更改它们的设置。

关于c# - XpsDocument 忽略我的高度设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24808436/

相关文章:

c# - .Net Remoting (C#) 的问题

wpf - 如何将自动完成框添加到数据网格?

wpf - 如何使用 DocumentViewer 显示流文档?

javascript - 为什么我自己的 "toString()"函数在我的 javascript 中不起作用?

php - 如何只打印属于当前帖子的类别?此代码段显示网站中的所有类别

Angular 6 Material 应用程序仅打印第一页

c# - 在 powershell 中获取 wpf 应用程序的退出代码

c# - 如何将数据库中的枚举保存为字符串

c# - 使用 Array.CopyTo 复制元素是否正确,还是应该始终使用 for 循环?

wpf - 如何将控件绑定(bind)到 ViewModel(MVVM 模式)中的 XmlDocument 元素?