如何在 UWP 中在多个页面上打印 [英] How to print on multiple pages in UWP

查看:34
本文介绍了如何在 UWP 中在多个页面上打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以在我的 UWP 项目中运行的打印系统.

为了准备我的打印内容,我使用了这个:

(来源:https://blogs.u2u.be/diederik/post/Printing-from-MVVM-XAML-Windows-8-Store-apps)

public void RegisterForPrinting(Page sourcePage, Type printPageType, object viewModel){this.callingPage = sourcePage;if (PrintingRoot == null){this.OnStatusChanged(new PrintServiceEventArgs("调用页面没有PrintingRoot Canvas."));返回;}this.printPageType = printPageType;this.DataContext = viewModel;//准备内容this.PreparePrintContent();//创建打印文档.打印文档 = 新打印文档();//保存文档源.打印文档源 = 打印文档.文档源;//添加一个创建预览页面的事件处理程序.printDocument.Paginate += PrintDocument_Paginate;//添加提供指定预览页面的事件处理程序.printDocument.GetPreviewPage += PrintDocument_GetPrintPreviewPage;//添加一个提供所有最终打印页面的事件处理程序.printDocument.AddPages += PrintDocument_AddPages;//创建一个 PrintManager 并添加一个用于打印初始化的处理程序.PrintManager printMan = PrintManager.GetForCurrentView();尝试{printMan.PrintTaskRequested += PrintManager_PrintTaskRequested;this.OnStatusChanged(new PrintServiceEventArgs("注册成功."));}捕获(无效操作异常){//可能已经注册了.this.OnStatusChanged(new PrintServiceEventArgs("您已经注册了."));}}

private void PreparePrintContent(){//创建并填充打印页面.var printPage = Activator.CreateInstance(this.printPageType) as Page;printPage.DataContext = this.DataContext;//创建打印模板页面并用空段落填充不可见的文本块.//这会将所有真实内容推入溢出.firstPage = new PrintPage();firstPage.AddContent(new Paragraph());//将内容从打印页面移动到打印模板 - 逐段.var printPageRtb = printPage.Content as RichTextBlock;while (printPageRtb.Blocks.Count > 0){var 段落 = printPageRtb.Blocks.First() 作为段落;printPageRtb.Blocks.Remove(段落);var container = parade.Inlines[0] as InlineUIContainer;如果(容器!= null){//将段落放在一个新的文本块中,并测量它.var measureRtb = new RichTextBlock();measureRtb.Blocks.Add(paragraph);打印Root.Children.Clear();打印Root.Children.Add(measureRtb);打印Root.InvalidateMeasure();打印Root.UpdateLayout();measureRtb.Blocks.Remove(段落);//应用行高触发溢出.段落.LineHeight = measureRtb.ActualHeight;}firstPage.AddContent(段落);};//将其发送到打印根.打印Root.Children.Clear();打印Root.Children.Add(firstPage);}

PrintPage

公共密封部分类 PrintPage : Page{公共打印页(){this.InitializeComponent();}公共打印页面(RichTextBlockOverflow textLinkContainer): 这个(){textLinkContainer.OverflowContentTarget = continuationPageLinkedContainer;}内部 void AddContent(段落块){this.textContent.Blocks.Add(block);}}

</RichTextBlock><RichTextBlockOverflow x:Name="continuationPageLinkedContainer" Grid.Row="2"/>

sourcePage

<!-- 内容--></RichTextBlock>

我的程序设置方式需要能够在单独的页面上打印 RichTextBox 的每个段落.

这可能吗?

解决方案

<块引用>

我需要能够在单独的页面上打印 RichTextBox 的每个段落.

如果要在单独的页面上打印 RichTextBox 的每个段落,则需要为每个段落创建多个 PrintPage,然后将 PrintPage 放入 PrintingRoot 和 PrintPages 列表.之后,当你添加预览页面时,你需要迭代PrintPages并添加它们.

我进行了以下更改,这是一个完整示例,您可以下载并查看.

private void PreparePrintContent(){打印Root.Children.Clear();//创建并填充打印页面.var printPage = Activator.CreateInstance(this.printPageType) as Page;printPage.DataContext = this.DataContext;var printPageRtb = printPage.Content as RichTextBlock;while (printPageRtb.Blocks.Count > 0){PrintPage firstPage = new PrintPage();firstPage.AddContent(new Paragraph());var 段落 = printPageRtb.Blocks.First() 作为段落;printPageRtb.Blocks.Remove(段落);firstPage.AddContent(段落);NeedToPrintPages.Add(firstPage);打印Root.Children.Add(firstPage);};}私有 RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastRTBOAdded, PrintPageDescription printPageDescription,int index){......if (lastRTBOAdded == null){//如果是第一页添加具体的场景内容page = NeedToPrintPages[index];}......}私有无效 PrintDocument_Paginate(对象发送者,PaginateEventArgs e){//清除预览页面的缓存printPreviewPages.Clear();this.pageNumber = 0;//清除预览页面的打印根打印Root.Children.Clear();for (int i = 0; i < NeedToPrintPages.Count; i++) {//此变量跟踪添加到将要打印的页面的最后一个 RichTextBlockOverflow 元素RichTextBlockOverflow lastRTBOOnPage;//获取打印任务选项PrintTaskOptions printOptions = ((PrintTaskOptions)e.PrintTaskOptions);//获取页面描述以确定页面有多大PrintPageDescription pageDescription = PrintingOptions.GetPageDescription(0);//我们知道至少有一页要打印.将 null 作为第一个参数传递给//AddOnePrintPreviewPage 告诉函数添加第一页.lastRTBOOnPage = AddOnePrintPreviewPage(null, pageDescription,i);//我们知道只要将最后一个 RichTextBoxOverflow 添加到打印预览中,就可以添加更多页面//页面有额外的内容while (lastRTBOOnPage.HasOverflowContent && lastRTBOOnPage.Visibility == Windows.UI.Xaml.Visibility.Visible){lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription,i);}}PrintDocument printDoc = (PrintDocument)sender;//报告创建的预览页数printDoc.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Intermediate);}

I have a printing system that functions in my UWP project.

To prepare my print content I use this:

(Sourced from: https://blogs.u2u.be/diederik/post/Printing-from-MVVM-XAML-Windows-8-Store-apps)

public void RegisterForPrinting(Page sourcePage, Type printPageType, object viewModel)
        {
            this.callingPage = sourcePage;

            if (PrintingRoot == null)
            {
                this.OnStatusChanged(new PrintServiceEventArgs("The calling page has no PrintingRoot Canvas."));
                return;
            }

            this.printPageType = printPageType;
            this.DataContext = viewModel;

            // Prep the content
            this.PreparePrintContent();

            // Create the PrintDocument.
            printDocument = new PrintDocument();

            // Save the DocumentSource.
            printDocumentSource = printDocument.DocumentSource;

            // Add an event handler which creates preview pages.
            printDocument.Paginate += PrintDocument_Paginate;

            // Add an event handler which provides a specified preview page.
            printDocument.GetPreviewPage += PrintDocument_GetPrintPreviewPage;

            // Add an event handler which provides all final print pages.
            printDocument.AddPages += PrintDocument_AddPages;

            // Create a PrintManager and add a handler for printing initialization.
            PrintManager printMan = PrintManager.GetForCurrentView();

            try
            {
                printMan.PrintTaskRequested += PrintManager_PrintTaskRequested;
                this.OnStatusChanged(new PrintServiceEventArgs("Registered successfully."));
            }
            catch (InvalidOperationException)
            {
                // Probably already registered.
                this.OnStatusChanged(new PrintServiceEventArgs("You were already registered."));
            }
        }

private void PreparePrintContent()
        {
            // Create and populate print page.
            var printPage = Activator.CreateInstance(this.printPageType) as Page;

            printPage.DataContext = this.DataContext;

            // Create print template page and fill invisible textblock with empty paragraph.
            // This pushes all real content into the overflow.
            firstPage = new PrintPage();
            firstPage.AddContent(new Paragraph());

            // Move content from print page to print template - paragraph by paragraph.
            var printPageRtb = printPage.Content as RichTextBlock;
            while (printPageRtb.Blocks.Count > 0)
            {
                var paragraph = printPageRtb.Blocks.First() as Paragraph;
                printPageRtb.Blocks.Remove(paragraph);

                var container = paragraph.Inlines[0] as InlineUIContainer;
                if (container != null)
                {
                    // Place the paragraph in a new textblock, and measure it.
                    var measureRtb = new RichTextBlock();
                    measureRtb.Blocks.Add(paragraph);
                    PrintingRoot.Children.Clear();
                    PrintingRoot.Children.Add(measureRtb);
                    PrintingRoot.InvalidateMeasure();
                    PrintingRoot.UpdateLayout();
                    measureRtb.Blocks.Remove(paragraph);

                    // Apply line height to trigger overflow.
                    paragraph.LineHeight = measureRtb.ActualHeight;
                }
                firstPage.AddContent(paragraph);
            };

            // Send it to the printing root.
            PrintingRoot.Children.Clear();
            PrintingRoot.Children.Add(firstPage);
        }

The PrintPage

public sealed partial class PrintPage : Page
    {
        public PrintPage()
        {
            this.InitializeComponent();
        }

        public PrintPage(RichTextBlockOverflow textLinkContainer)
            : this()
        {
            textLinkContainer.OverflowContentTarget = continuationPageLinkedContainer;
        }

        internal void AddContent(Paragraph block)
        {
            this.textContent.Blocks.Add(block);
        }
    }

<RichTextBlock x:Name="textContent"
                           Grid.Row="1"
                           Grid.ColumnSpan="2"
                           FontSize="18"
                           OverflowContentTarget="{Binding ElementName=continuationPageLinkedContainer}"
                           IsTextSelectionEnabled="True"
                           TextAlignment="Left"
                           FontFamily="Segoe UI"
                           VerticalAlignment="Top"
                           HorizontalAlignment="Left">
</RichTextBlock>

<RichTextBlockOverflow x:Name="continuationPageLinkedContainer" Grid.Row="2" />

The sourcePage

<RichTextBlock x:Name="PrintContent">
        <!-- Content -->
    </RichTextBlock>

The way I have my program setup I need to be able to print each paragraph of the RichTextBox on separate pages.

Is this possible?

解决方案

I need to be able to print each paragraph of the RichTextBox on separate pages.

If you want to print each paragraph of the RichTextBox on separate page, you need to create mutiple PrintPages for each paragraph, then put the PrintPage to the PrintingRoot and a list of PrintPages. After that, when you add the preview pages, you need to iterate PrintPages and add them.

I made the following changes and here is a complete sample, you can download and check it.

private void PreparePrintContent()
{
    PrintingRoot.Children.Clear();
    // Create and populate print page.
    var printPage = Activator.CreateInstance(this.printPageType) as Page;

    printPage.DataContext = this.DataContext;

    var printPageRtb = printPage.Content as RichTextBlock;
    while (printPageRtb.Blocks.Count > 0)
    {
        PrintPage firstPage = new PrintPage();
        firstPage.AddContent(new Paragraph());
        var paragraph = printPageRtb.Blocks.First() as Paragraph;
        printPageRtb.Blocks.Remove(paragraph);

        firstPage.AddContent(paragraph);
        NeedToPrintPages.Add(firstPage);
        PrintingRoot.Children.Add(firstPage);
    };
}

private RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastRTBOAdded, PrintPageDescription printPageDescription,int index)
{
    ......
    if (lastRTBOAdded == null)
    {
        // If this is the first page add the specific scenario content
        page = NeedToPrintPages[index];
    }
    ......
}

private void PrintDocument_Paginate(object sender, PaginateEventArgs e)
{
    // Clear the cache of preview pages 
    printPreviewPages.Clear();
    this.pageNumber = 0;

    // Clear the printing root of preview pages
    PrintingRoot.Children.Clear();
    for (int i = 0; i < NeedToPrintPages.Count; i++) {
        // This variable keeps track of the last RichTextBlockOverflow element that was added to a page which will be printed
        RichTextBlockOverflow lastRTBOOnPage;
        // Get the PrintTaskOptions
        PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);

        // Get the page description to deterimine how big the page is
        PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);

        // We know there is at least one page to be printed. passing null as the first parameter to
        // AddOnePrintPreviewPage tells the function to add the first page.
        lastRTBOOnPage = AddOnePrintPreviewPage(null, pageDescription,i);

        // We know there are more pages to be added as long as the last RichTextBoxOverflow added to a print preview
        // page has extra content
        while (lastRTBOOnPage.HasOverflowContent && lastRTBOOnPage.Visibility == Windows.UI.Xaml.Visibility.Visible)
        {
            lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription,i);
        }

    }

    PrintDocument printDoc = (PrintDocument)sender;

    // Report the number of preview pages created
    printDoc.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Intermediate);
}

这篇关于如何在 UWP 中在多个页面上打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆