可以简化此 FlowDocument 的打印吗?

Hui Liu-MSFT 44,631 信誉分 Microsoft 供应商
2024-05-20T08:21:14.2633333+00:00

我有一个 ICommand,PrintReport。它的执行函数执行以下操作:

void printReport(object o)
{
    var dialog = new PrintDialog()
    {
        CurrentPageEnabled = true,
        UserPageRangeEnabled = true
    };
    if (dialog.ShowDialog() == true)
    {
        var size = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight);               
        FlowPaginator.PageWidth = size.Width;
        FlowPaginator.PageHeight = size.Height;
        CreateReport(size);
        dialog.PrintDocument(new FlowPaginator(document) { PageSize = size }, string.Empty);
    }
}

FlowPaginator 是 DocumentPaginator 的一个子类,当我创建 FlowDocument 时,我找不到直接在其中添加 Header 和 Footer 的方法,因此我将它们添加到此类中。首先,我创建 FlowDocument 文档,然后将其传递给 PrintDocument 方法中的新 FlowPaginator。

void CreateReport(Size pageSize)
{
    document = new FlowDocument()
    {
        PageWidth = pageSize.Width,
        PageHeight = pageSize.Height,
        PagePadding = new Thickness(FlowPaginator.Margin,
                                    Header(pageSize).DesiredSize.Height,
                                    FlowPaginator.Margin,
                                    FlowPaginator.Margin)
    };    
    var table = new Table()
    {
        FontFamily = SystemFonts.MessageFontFamily,
        FontStyle = SystemFonts.MessageFontStyle,
        FontSize = 11.0,
        CellSpacing = 0,
        Columns =
        {
            new TableColumn(){ Width = new GridLength(ColumnWidth) },
            new TableColumn(){ Width = new GridLength(pageSize.Width - (2.0 * FlowPaginator.Margin) - (4 * ColumnWidth)) },
            new TableColumn(){ Width = new GridLength(ColumnWidth) },
            new TableColumn(){ Width = new GridLength(ColumnWidth) },
            new TableColumn(){ Width = new GridLength(ColumnWidth) },
        }
    };
    var rowNum = 1;   
    foreach (var item in Reportables)
    {
        var rowGroup = new TableRowGroup();
        var row = new TableRow();
        row.Cells.Add(new TableCell(new Paragraph(new Run(item.Date.ToString("dd/MM/yyyy")))));
        row.Cells.Add(new TableCell(new Paragraph(new Run(item.Particulars))));
        row.Cells.Add(new TableCell(new Paragraph(new Run(item.Receivable.ToString("#,##0;(#,##0);-    ")))) { TextAlignment = TextAlignment.Right });
        row.Cells.Add(new TableCell(new Paragraph(new Run(item.Receipt.ToString("#,##0;(#,##0);-    ")))) { TextAlignment = TextAlignment.Right });
        row.Cells.Add(new TableCell(new Paragraph(new Run(item.Balance.ToString("#,##0;(#,##0);-    ")))) { TextAlignment = TextAlignment.Right });    
        if (rowNum % 2 == 0) row.Background = Brushes.LightBlue;    
        rowGroup.Rows.Add(row);
        table.RowGroups.Add(rowGroup);
        rowNum++;
    }
    document.Blocks.Add(table);
}

为了在 Flowdocument 的每一页上都留出空间放置 Header,我调用了一个函数 Header(pageSize).DesiredSize.Height,该函数在 PagePadding 中返回一个 UIElement。并且对于我的表格报告的每一列,我指定了 TableColumn Width。FlowPaginator 类中包含以下内容:

public class FlowPaginator : DocumentPaginator
{
    public static double PageWidth, PageHeight;
    public const double Margin = 96.0;
    DocumentPaginator paginator;    
    public FlowPaginator(FlowDocument document)
    {
        paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
    }
    public override bool IsPageCountValid => paginator.IsPageCountValid;
    public override int PageCount => paginator.PageCount;
    public override Size PageSize { get => paginator.PageSize; set => paginator.PageSize = value; }
    public override IDocumentPaginatorSource Source => paginator.Source;
    public override DocumentPage GetPage(int pageNumber)
    {
        return new DocumentPage(new ContainerVisual() 
        { 
            Children =
            {
                LedgerVM.Header(PageSize),
                paginator.GetPage(pageNumber).Visual,
                Footer(++pageNumber)
            }
        });
    }    
    UIElement Footer(int pageNo){ ... }
}

在 GetPage 中,我必须调用 CreateReport 方法中使用的相同静态 Header 函数来添加页眉,然后添加填充内容,最后必须调用同一类的另一个函数 Footer 来获取每页的页脚。

我想对 FlowDocument 的第二列使用 GridUnitType.Star,对其余 4 列使用 GridLength.Auto,但到目前为止我还没有找到任何方法可以做到这一点,而且我还想在创建 FlowDocument 时直接在其中添加 Header/Footer,有什么方法可以做到这一点,或者可以进一步简化这个过程吗?

Note:此问题总结整理于:May printing this FlowDocument be simplified?

Windows Presentation Foundation
Windows Presentation Foundation
.NET Framework 的一部分,它提供统一的编程模型,用于在 Windows 上构建业务线桌面应用程序。
76 个问题
0 个注释 无注释
{count} 票

接受的答案
  1. Jiale Xue - MSFT 38,931 信誉分 Microsoft 供应商
    2024-05-20T09:12:09.79+00:00

    如何在 FlowPaginator 中添加页眉和页脚,如下所示:

    public class FlowPaginator: DocumentPaginator  
        {  
            DocumentPaginator m_paginator;  
      
            public DocumentPage GetPage(int pageNumber)  
            {  
                DocumentPage page = m_paginator.GetPage(pageNumber);  
                ContainerVisual newpage = new ContainerVisual();  
      
                //Header  
                DrawingVisual header = new DrawingVisual();  
                using (DrawingContext ctx = header.RenderOpen())  
                {  
                    //content for Header     
                }  
      
                DrawingVisual footer = new DrawingVisual();  
                using (DrawingContext ctx = footer.RenderOpen())  
                {  
                    //content for Footer  
                }  
      
                ContainerVisual mainPage = new ContainerVisual();  
                mainPage.Children.Add(page.Visual);  
                mainPage.Transform = new MatrixTransform(1, 0, 0, 0.95, 0, 0.025 * page.ContentBox.Height);  
      
                newpage.Children.Add(mainPage);  
                newpage.Children.Add(header);  
                newpage.Children.Add(footer);  
      
                return new DocumentPage(newpage, page.Size, page.BleedBox, page.ContentBox);  
            }  
        }  
    

    如果答案是正确的,请点击“接受答案”并点赞。 如果您对此答案还有其他疑问,请点击“评论”。

    注意:如果您想接收相关电子邮件,请按照我们的文档中的步骤启用电子邮件通知 此线程的通知。

    0 个注释 无注释

0 个其他答案

排序依据: 非常有帮助