首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >中的FixedPage XPS/PDF内容不会填满页面

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

Stack Overflow用户
提问于 2021-10-14 17:30:02
回答 1查看 71关注 0票数 0

我已经尝试了几个小时,现在很不情愿地请求帮助。

我有一个带有背景视图模型的WPF自定义控件,我想要打印到PDF (通过XPS)。最终,这些控件将有多个页面。

按照SO和MSDN论坛上的几个示例,我已经编写了一些代码来创建包含控件的PDF文件,但内容的大小不正确。

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

生成的PDF:

我期待内容填满页面,如果它显示在WPF窗口中:

我尝试了所有我能想到的测量,安排,更新布局调用的组合,但都没有成功。

我也尝试过不同的XPS to PDF解决方案(PDFSharp和Print FixedDocument/XPS to PDF without showing file save dialog),但都没有成功。

我在这里有一个关于GitHub的最小的工作示例:https://github.com/AndyStagg/PDFPrintingDemo

相关资源:

Convert WPF (XAML) Control to XPS Document

How to calculate FixedPage dimensions

Why do I have have to use UIElement.UpdateLayout?

编辑:我尝试了更多的东西:

在固定页面上设置水平和垂直对齐方式

代码语言:javascript
复制
fixedPage.HorizontalAlignment = HorizontalAlignment.Stretch;
fixedPage.VerticalAlignment = VerticalAlignment.Stretch;

在控件上设置水平和垂直(常规和内容)对齐方式

代码语言:javascript
复制
controlView.HorizontalContentAlignment = HorizontalAlignment.Stretch;
controlView.VerticalContentAlignment = VerticalAlignment.Stretch;

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

controlView.DesiredSize是155x215,所以我尝试在Arrage调用中指定pageSize

代码语言:javascript
复制
controlView.Arrange(new Rect(pageSize));

这导致PDF具有正确的ActualHeightActualWidth,但得到的controlView保持不变。

我已经尝试将pageSize发送到度量调用

代码语言:javascript
复制
controlView.Measure(pageSize);

不走运。

最后但同样重要的是,我尝试在控件上设置宽度和高度

代码语言:javascript
复制
controlView.Width = pageSize.Width;
controlView.Height = pageSize.Height;

再说一次,祝你好运。

我还尝试将controlView作为子元素放在边框、ViewBox和网格中

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

以及尝试调用孩子上的度量和排列调用(controlView)

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

在这一点上,我完全被难住了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-14 21:00:16

在尝试了几乎所有我能想到的创建文档和固定页面的逻辑之后,我转向了UserControl本身,在那之后,修复它出奇地容易。

我在UserControl上使用了MeasuredOverride方法来查看父级是否为FixedPage,如果是,则根据固定的页面宽度和高度返回一个大小,否则返回基本逻辑。这允许控件仍然在UI中用于预览等。

它当然不是很漂亮,但它是有效的。我肯定它会有一些陷阱,但至少我可以继续弄清楚这些陷阱可能是什么。

代码语言:javascript
复制
protected override Size MeasureOverride(Size constraint)
{
    if (this.Parent is FixedPage fixedPage)
    {
        return new Size(fixedPage.Width, fixedPage.Height);
    }

    return base.MeasureOverride(constraint);
}

GitHub存储库已更新,以便将来查看完整的解决方案。

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

https://stackoverflow.com/questions/69574980

复制
相关文章

相似问题

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