首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF FixedDocument分页

WPF FixedDocument分页
EN

Stack Overflow用户
提问于 2011-02-25 00:59:06
回答 3查看 9.7K关注 0票数 10

如何让FixedDocument自动分页?我有以下代码,我可以用来把美化面板到一个DocViewer。当面板扩展到超过一个页面时,就会出现问题。现在,我们只需裁剪。基本上,我想创建一种相当通用的方法来打印用户正在查看的内容。我的方法合理吗?

代码语言:javascript
复制
    public void CreateReport(Panel details)
    {
        FixedDocument fixedDoc = new FixedDocument();
        PageContent pageContent = new PageContent();
        FixedPage fixedPage = new FixedPage();

        fixedPage.DataContext = this.DataContext;
        fixedPage.Margin = new Thickness(10);

        fixedPage.Children.Add(details);
        ((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
        fixedDoc.Pages.Add(pageContent);

        // This makes the array of controls invisibile, then climbs the details structure
        // and makes the controls within details appropriate for the DocumentViewwer (i.e. TextBoxes are
        // non-editable, no borders, no scroll bars, etc).
        prePrintPrepare(details, fixedPage, new FrameworkElement[] { controlToMakeInvisible });

        _dv = new DocViewer();
        _dv.documentViewer1.Document = fixedDoc;
        _dv.Show();
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-25 04:10:34

我讨厌回答我自己的问题,但是,下面给了我一个合理的解决方案:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bd89e0d2-73df-4b9b-9210-b8be83ff29d6/

史考特

代码语言:javascript
复制
public static class PrintHelper
{
    public static FixedDocument GetFixedDocument(FrameworkElement toPrint, PrintDialog printDialog)
    {
        PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
        Size pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
        Size visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
        FixedDocument fixedDoc = new FixedDocument();

        // If the toPrint visual is not displayed on screen we neeed to measure and arrange it.
        toPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        toPrint.Arrange(new Rect(new Point(0, 0), toPrint.DesiredSize));

        Size size = toPrint.DesiredSize;

        // Will assume for simplicity the control fits horizontally on the page.
        double yOffset = 0;
        while (yOffset < size.Height)
        {
            VisualBrush vb = new VisualBrush(toPrint);
            vb.Stretch = Stretch.None;
            vb.AlignmentX = AlignmentX.Left;
            vb.AlignmentY = AlignmentY.Top;
            vb.ViewboxUnits = BrushMappingMode.Absolute;
            vb.TileMode = TileMode.None;
            vb.Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height);

            PageContent pageContent = new PageContent();
            FixedPage page = new FixedPage();
            ((IAddChild)pageContent).AddChild(page);
            fixedDoc.Pages.Add(pageContent);
            page.Width = pageSize.Width;
            page.Height = pageSize.Height;

            Canvas canvas = new Canvas();
            FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
            FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
            canvas.Width = visibleSize.Width;
            canvas.Height = visibleSize.Height;
            canvas.Background = vb;
            page.Children.Add(canvas);

            yOffset += visibleSize.Height;
        }
        return fixedDoc;
    }

    public static void ShowPrintPreview(FixedDocument fixedDoc)
    {
        Window wnd = new Window();
        DocumentViewer viewer = new DocumentViewer();
        viewer.Document = fixedDoc;
        wnd.Content = viewer;
        wnd.ShowDialog();
    }
}
票数 5
EN

Stack Overflow用户

发布于 2020-02-11 15:31:12

对于那些对不同的、也许更“高级”的解决方案感兴趣的人,请继续查看XAML on GitHub,在那里我演示了如何创建my repository报表、对报表进行分页,然后从报表生成可打印的FixedDocument。

魔术发生在Paginator.cs中,代码遍历所有自定义附加属性,并使用它们来确定在哪里设置页码,哪些元素仅在第一页显示,等等……

所有报表都定义为普通的XAML用户控件,并在完成分页后转换为固定页。好处是您可以用纯XAML定义文档/报告,添加一些附加属性,然后分页器代码就可以完成剩下的工作。

票数 2
EN

Stack Overflow用户

发布于 2020-08-15 18:40:53

这个问题已经有很长一段时间没有回答了。

我尝试了Doo Dah的答案,但问题是它不会处理流文档的页面填充。

因此,我写了自己的解决方案(Doo Dah的答案帮助我完成了它):

代码语言:javascript
复制
public FixedDocument Get_Fixed_From_FlowDoc(FlowDocument flowDoc, PrintDialog printDlg)
{
    var fixedDocument = new FixedDocument();
    try
    {
        pdlgPrint = printDlg ?? new PrintDialog();

        DocumentPaginator dpPages = (DocumentPaginator)((IDocumentPaginatorSource)flowDoc).DocumentPaginator;
        dpPages.ComputePageCount();
        PrintCapabilities capabilities = pdlgPrint.PrintQueue.GetPrintCapabilities(pdlgPrint.PrintTicket);

        for (int iPages= 0; iPages < dpPages.PageCount; iPages++)
        {
            var page = dpPages.GetPage(iPages);
            var pageContent = new PageContent();
            var fixedPage = new FixedPage();

            Canvas canvas = new Canvas();

            VisualBrush vb = new VisualBrush(page.Visual);
            vb.Stretch = Stretch.None;
            vb.AlignmentX = AlignmentX.Left;
            vb.AlignmentY = AlignmentY.Top;
            vb.ViewboxUnits = BrushMappingMode.Absolute;
            vb.TileMode = TileMode.None;
            vb.Viewbox = new Rect(0, 0, capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);

            FixedPage.SetLeft(canvas, 0);
            FixedPage.SetTop(canvas, 0);
            canvas.Width = capabilities.PageImageableArea.ExtentWidth;
            canvas.Height = capabilities.PageImageableArea.ExtentHeight;
            canvas.Background = vb;

            fixedPage.Children.Add(canvas);

            fixedPage.Width = pdlgPrint.PrintableAreaWidth;
            fixedPage.Height = pdlgPrint.PrintableAreaHeight;
            pageContent.Child = fixedPage;
            fixedDocument.Pages.Add(pageContent);
        }
        dv1.ShowPageBorders = true;
    }
    catch (Exception)
    {
        throw;
    }
    return fixedDocument;
}

您必须为之前将要显示的内容构建一个FlowDocument,并将其传递给该方法。

添加了PrintDialog变量以从我的预览窗口调用该方法,并可以传递当前打印机设置。

如果您从主程序调用它,您可以传递new PrintDialog()null,这没有区别,因为如果您传递null,它将创建一个new PrintDialog

对于不同类型的文本(标题、文本、字体)的Flowdocument,这对我来说工作得很好。

它应该适用于图片和文本混合,或者只使用图片-它使用的是视觉效果,而不是来自流程文档的特定内容,因此它也应该适用于分页。

我没有尝试Shahin Dohan的答案,因为这是经常出现的问题。

它是在MVVM上编写的,当其他人编写它时,它很难理解。

在我看来,写一个没有mvvm的小示例程序会更好,人们可以熟练地使用mvvm,或者只使用代码。

我理解mvvm的机会,但要向某人展示如何工作,我看到的只是缺点(如果你不展示特定的mvvm技师)

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

https://stackoverflow.com/questions/5107880

复制
相关文章

相似问题

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