简体   繁体   English

FixedPage XPS/PDF 内容不会填满页面

[英]FixedPage XPS/PDF content in won't fill the page

I've been attempting this for a few hours, and now reluctantly asking for help.我已经尝试了几个小时,现在不情愿地寻求帮助。

I have a WPF Custom Control with a backing view model that I'd like to print to PDF (via XPS).我有一个带有支持视图模型的 WPF 自定义控件,我想将其打印为 PDF(通过 XPS)。 Eventually, there will be multiple pages of these controls.最终,这些控件会有多个页面。

Following several examples on SO and MSDN forums, I've written code that will create the PDF file with the control in it, but the content is not sized correctly.按照 SO 和 MSDN 论坛上的几个示例,我编写了代码来创建带有控件的 PDF 文件,但内容的大小不正确。

    var controlViewModelsToPrint = new InfoControlViewModel[] { ViewModel };

    // Assume 8.5"x11" size for now, get from print dialog later
    var xpsDPI = 96;
    var pageWidth = 8.5 * xpsDPI;
    var pageHeight = 11 * xpsDPI;

    var pageSize = new Size(pageWidth, pageHeight);

    // Document hierarchy: FixedDocument > PageContent > FixedPage > UIElement/Control

    var fixedDoc = new FixedDocument();

    foreach (var controlViewModel in controlViewModelsToPrint)
    {
        var pageContent = new PageContent();
        var fixedPage = new FixedPage();

        // The control to be printed is never displayed on screen so measure and arrage it.
        var controlView = new InfoControl(controlViewModel);

        controlView.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        // I've read that using either this call to the dispatcher or an UpdateLayout would help - it doesn't.
        //Application.Current.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
        controlView.Arrange(new Rect(controlView.DesiredSize));

        // Add the control/page/content through the document hierarchy
        fixedPage.Children.Add(controlView);
        ((IAddChild)pageContent).AddChild(fixedPage);

        // Set gage dimensions
        fixedPage.Width = pageSize.Width;
        fixedPage.Height = pageSize.Height;

        // Running Measure/Arrage on the fixed page does not alter the result.
        fixedPage.Measure(pageSize);
        fixedPage.Arrange(new Rect(fixedPage.DesiredSize));
        fixedPage.UpdateLayout();

        fixedDoc.Pages.Add(pageContent);
    }

    PrintFixedDocument(fixedDoc);

Resulting PDF:结果PDF: 结果内容未填充到页面 I am expecting the content to fill the page, is it would if it were displayed in a WPF window:我期待内容填满页面,如果它显示在 WPF 窗口中会不会: 控件在 WPF 窗口中正确显示

I have tried every combination of measuring, arranging, updating layout calls I can think of without success.我尝试了所有我能想到的测量、安排、更新布局调用的组合,但都没有成功。

I have also tried different XPS to PDF solutions(PDFSharp, and Print FixedDocument/XPS to PDF without showing file save dialog ) without success.我还尝试了不同的 XPS 到 PDF 解决方案(PDFSharp 和Print FixedDocument/XPS to PDF 而没有显示文件保存对话框),但没有成功。

I have a minimal working example on GitHub here: https://github.com/AndyStagg/PDFPrintingDemo我在 GitHub 上有一个最小的工作示例: https : //github.com/AndyStagg/PDFPrintingDemo

Relivent resources:重温资源:

Convert WPF (XAML) Control to XPS Document 将 WPF (XAML) 控件转换为 XPS 文档

How to calculate FixedPage dimensions 如何计算 FixedPage 尺寸

Why do I have have to use UIElement.UpdateLayout? 为什么我必须使用 UIElement.UpdateLayout?

Edit: I've tried a few more things:编辑:我尝试了更多的东西:

Setting the Horizontial and Vertical alignment on the fixed page在固定页面上设置水平和垂直对齐

fixedPage.HorizontalAlignment = HorizontalAlignment.Stretch;
fixedPage.VerticalAlignment = VerticalAlignment.Stretch;

Setting the Horizontal and Vertical (both regular, and Content) alignment on the control在控件上设置水平和垂直(常规和内容)对齐方式

controlView.HorizontalContentAlignment = HorizontalAlignment.Stretch;
controlView.VerticalContentAlignment = VerticalAlignment.Stretch;

controlView.HorizontalAlignment = HorizontalAlignment.Stretch;
controlView.VerticalAlignment = VerticalAlignment.Stretch;

controlView.DesiredSize was 155x215, so I tried specifying the pageSize in the Arrage call controlView.DesiredSize是 155x215,所以我尝试在 Arrage 调用中指定pageSize

controlView.Arrange(new Rect(pageSize));

Which results in the controlView objet having the correct ActualHeight and ActualWidth , but resulting PDF is unchanged.这导致controlView对象具有正确的ActualHeightActualWidth ,但生成的 PDF 未更改。

I've tried sending in the pageSize to the Measure call我试过将pageSize发送到 Measure 调用

controlView.Measure(pageSize);

No luck.没运气。

And last but not least, I tried to set the width and height on the control最后但并非最不重要的是,我尝试在控件上设置宽度和高度

controlView.Width = pageSize.Width;
controlView.Height = pageSize.Height;

Again, No Luck.再次,没有运气。

I've also tried placing the controlView as a child within a Border, ViewBox, and a Grid我还尝试将controlView作为子项放置在 Border、ViewBox 和 Grid 中

var border = new Border();
var controlView = new InfoControl(control);
border.Child = controlView;

border.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
border.Arrange(new Rect(border.DesiredSize));

// Add the control/page/content through the document hierarchy
fixedPage.Children.Add(border);

as well as tried calling the Measure & Arrange calls on the child (controlView)以及尝试调用子项上的测量和排列调用(controlView)

var grid = new Grid();
var controlView = new InfoControl(control);

grid.Children.Add(controlView);

controlView.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
controlView.Arrange(new Rect(controlView.DesiredSize));

// Add the control/page/content through the document hierarchy
fixedPage.Children.Add(grid);

I am pretty thoroughly stumped at this point.在这一点上,我完全被难住了。

After trying pretty much everything I could think of in the logic for creating the document and fixed page, I turned to the UserControl itself, and after that, it was surprisingly easy to fix.在尝试了几乎所有我能想到的创建文档和固定页面的逻辑之后,我转向了UserControl本身,之后,修复起来非常容易。

I used the MeasuredOverride method on the UserControl to see if the parent was a FixedPage and if it was, to return a size based on the fixed page width and height, otherwise return the base logic.我在UserControl上使用了MeasuredOverride方法来查看父级是否为FixedPage ,如果是,则返回基于固定页面宽度和高度的大小,否则返回基本逻辑。 That allows the control to still be used in the UI for previewing, etc..这允许控件仍然在 UI 中用于预览等。

It sure isn't pretty, but it works.它肯定不漂亮,但它有效。 I am sure there will be some pitfalls with it, but at least I can keep going to figure out what those might be.我相信它会有一些陷阱,但至少我可以继续弄清楚那些可能是什么。

protected override Size MeasureOverride(Size constraint)
{
    if (this.Parent is FixedPage fixedPage)
    {
        return new Size(fixedPage.Width, fixedPage.Height);
    }

    return base.MeasureOverride(constraint);
}

The GitHub repo is updated for those in the future to view the complete solution. GitHub 存储库已更新,以便将来查看完整的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM