【问题标题】:How to show multiple pages in Print Preview UI and print all pages in UWP app?如何在打印预览 UI 中显示多个页面并在 UWP 应用程序中打印所有页面?
【发布时间】:2019-09-16 08:02:52
【问题描述】:

我需要通过我的 UWP 应用打印一个列表。由于 List 可以有 N 个项目,所以我需要根据它在我的打印预览中显示页面,然后将它们全部打印出来。 我尝试了一些场景并查看了 Microsoft 提供的 UWP Print 应用程序示例,但他们使用 RichTextBlock 在内容溢出时显示所有页面。但是我有一个列表,所以我不知道我的内容何时溢出。它只在打印预览 UI 中显示第一页。

我也根据 A4 纸的尺寸计算了总页数。 下面是我的 C# 代码:

 if (PrintManager.IsSupported())
                            {
                                printDoc = new PrintDocument();
                                printDocSource = printDoc.DocumentSource;
                                _totalPages = (int)Math.Ceiling(wholeItemsListForPDF.Count / (double)15);
                                tempList = new ManifestPDFDataModel();
                                tempList = _manifestPDFDataModel;
                                printDoc.Paginate += PaginateManifestLabel;
                                for (int i = 1; i <= _totalPages; i++)
                                {
                                    printDoc.GetPreviewPage += GetPreviewPageManifestLabel;
                                    printDoc.AddPages += AddPagesManifestLabel;
                                    if (i != _totalPages)
                                    {
                                        _manifestPDFDataModel.ItemsPDFList.RemoveRange(0, 15);
                                        tempList.ItemsPDFList = _manifestPDFDataModel.ItemsPDFList;
                                    }
                                }
                                printMan = PrintManager.GetForCurrentView();
                                printMan.PrintTaskRequested += PrintTaskRequestedManifestLabel;

                                //printHelper = new PrintHelper(this);
                                //printHelper.RegisterForPrinting();

                                //// Initialize print content for this scenario
                                //printHelper.PreparePrintContent(new GenericManifestPDF(_manifestPDFDataModel));

                                try
                                {
                                    // Show print UI
                                    await PrintManager.ShowPrintUIAsync();
                                }
                                catch (Exception ex)
                                {
                                    // Printing cannot proceed at this time
                                    ContentDialog noPrintingDialog = new ContentDialog()
                                    {
                                        Title = "Printing error",
                                        Content = "\nSorry, printing can' t proceed at this time.",
                                        PrimaryButtonText = "OK"
                                    };
                                    printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
                                    printDoc.Paginate -= PaginateManifestLabel;
                                    printDoc.GetPreviewPage -= GetPreviewPageManifestLabel;
                                    printDoc.AddPages -= AddPagesManifestLabel;
                                    await noPrintingDialog.ShowAsync();
                                }
                            }
                            else
                            {
                                // Printing is not supported on this device
                                ContentDialog noPrintingDialog = new ContentDialog()
                                {
                                    Title = "Printing not supported",
                                    Content = "\nSorry, printing is not supported on this device.",
                                    PrimaryButtonText = "OK"
                                };
                                printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
                                printDoc.Paginate -= PaginateManifestLabel;
                                printDoc.GetPreviewPage -= GetPreviewPageManifestLabel;
                                printDoc.AddPages -= AddPagesManifestLabel;
                                await noPrintingDialog.ShowAsync();
                            }

所有与打印相关的事件:

 public void PrintTaskRequestedManifestLabel(PrintManager sender, PrintTaskRequestedEventArgs args)
    {
        // Create the PrintTask.
        // Defines the title and delegate for PrintTaskSourceRequested
        var printTask = args.Request.CreatePrintTask("Print", PrintTaskSourceRequestedManifestLabel);

        // Handle PrintTask.Completed to catch failed print jobs
        printTask.Completed += PrintTaskCompletedManifestLabel;

    }
    /// <summary>
    /// PrintTaskSourceRequestedManifestLabel
    /// </summary>
    /// <param name="args">PrintTaskSourceRequestedArgs</param>
    public void PrintTaskSourceRequestedManifestLabel(PrintTaskSourceRequestedArgs args)
    {
        // Set the document source.
        args.SetSource(printDocSource);
    }


    #region Print preview
    /// <summary>
    /// Pagination Manifest Label
    /// </summary>
    /// <param name="sender">pass sender object</param>
    /// <param name="e">PaginateEventArgs</param>
    public void PaginateManifestLabel(object sender, PaginateEventArgs e)
    {
        // As I only want to print one Rectangle, so I set the count to 1
        printDoc.SetPreviewPageCount(_totalPages, PreviewPageCountType.Intermediate);
    }
    /// <summary>
    /// Print Preview Page ManifestLabel SetPreviewPage
    /// </summary>
    /// <param name="sender">pass sender object</param>
    /// <param name="e">GetPreviewPageEventArgs</param>
    public void GetPreviewPageManifestLabel(object sender, GetPreviewPageEventArgs e)
    {
        // Provide a UIElement as the print preview.
        printDoc.SetPreviewPage(e.PageNumber, new GenericManifestPDF(tempList));
    }

    #endregion

    #region Add pages to send to the printer
    /// <summary>
    /// Add Pages ManifestLabel
    /// </summary>
    /// <param name="sender">pass sender object</param>
    /// <param name="e">AddPagesEventArgs</param>
    public void AddPagesManifestLabel(object sender, AddPagesEventArgs e)
    {
        printDoc.AddPage(new GenericManifestPDF(tempList));

        // Indicate that all of the print pages have been provided
        printDoc.AddPagesComplete();
    }

    #endregion

    #region Print task completed
    /// <summary>
    /// Print Task Completed ManifestLabel 
    /// </summary>
    /// <param name="sender">PrintTask</param>
    /// <param name="args">PrintTaskCompletedEventArgs</param>
    public async void PrintTaskCompletedManifestLabel(PrintTask sender, PrintTaskCompletedEventArgs args)
    {
        // Notify the user when the print operation fails.
        if (args.Completion == PrintTaskCompletion.Failed)
        {
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
            {
                ContentDialog noPrintingDialog = new ContentDialog()
                {
                    Title = "Printing error",
                    Content = "\nSorry, failed to print.",
                    PrimaryButtonText = "OK"
                };
                printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
                printDoc.Paginate -= PaginateManifestLabel;
                printDoc.GetPreviewPage -= GetPreviewPageManifestLabel;
                printDoc.AddPages -= AddPagesManifestLabel;
                await noPrintingDialog.ShowAsync();
            });
        }
        else
        {
            printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
            //printDoc.Paginate -= Paginate;
            //printDoc.GetPreviewPage -= GetPreviewPage;
            //printDoc.AddPages -= AddPages;
        }
    }

    #endregion

XAML 页面代码:

<Grid>

    <Grid.RowDefinitions>
        <RowDefinition Height="30*"/>
        <RowDefinition Height="70*"/>
    </Grid.RowDefinitions>

    <Grid BorderBrush="Black" BorderThickness="2" Margin="30">
        <Grid.RowDefinitions>
            <RowDefinition Height="80*"/>
            <RowDefinition Height="20*"/>
        </Grid.RowDefinitions>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <TextBlock Text="Manifest PDF Report" Foreground="Black" FontWeight="Bold" Margin="20,20,0,0"/>
                <TextBlock x:Name="Function" Foreground="Black" Grid.Row="1" FontWeight="Bold" Margin="20,20,0,0"/>
                <TextBlock x:Name="Counts" Grid.Row="2" Foreground="Black" FontWeight="Bold" Margin="20,20,0,0"/>
            </Grid>
            <Grid Grid.Column="1">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <TextBlock x:Name="PrintedValue" Foreground="Black" FontWeight="Bold" Margin="20,20,0,0"/>
                <TextBlock x:Name="RouteValue" Foreground="Black" Grid.Row="1" FontWeight="Bold" Margin="20,20,0,0"/>
                <TextBlock x:Name="BatchIDValue" Grid.Row="2" Foreground="Black" FontWeight="Bold" Margin="20,20,0,0"/>
            </Grid>
            <Grid Grid.Column="2">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Image x:Name="BarcodeImage" Margin="20,0,0,0" HorizontalAlignment="Center"/>
                <TextBlock x:Name="BatchBarcodeText" Grid.Row="1" Foreground="Black" FontWeight="Bold" Margin="20,20,0,0"/>
            </Grid>
        </Grid>
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="Delivered By :" Foreground="Black" Margin="20,0,0,0" VerticalAlignment="Center"/>
            <TextBlock Text="Batch Delivery Time :" Foreground="Black" Grid.Column="1" Margin="20,0,0,0" VerticalAlignment="Center"/>
        </Grid>
    </Grid>
    <Grid Grid.Row="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="90*"/>
        </Grid.RowDefinitions>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock FontWeight="Bold" Text="BILL#" Foreground="Black" TextDecorations="Underline" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="1" Foreground="Black" TextDecorations="Underline" Text="Carrier" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="2" Foreground="Black" TextDecorations="Underline" Text="Package" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="3" Foreground="Black" TextDecorations="Underline" Text="Location" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="4" Text="ItemType" Foreground="Black" TextDecorations="Underline" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="5" Foreground="Black" TextDecorations="Underline" Text="Deliver To" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="6" Foreground="Black" TextDecorations="Underline" Text="Sender" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="7" Foreground="Black" TextDecorations="Underline" Text="Date" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="8" Foreground="Black" TextDecorations="Underline" Text="PO" Margin="20,20,0,0"/>
            <TextBlock FontWeight="Bold" Grid.Column="9" Foreground="Black" TextDecorations="Underline" Text="Control" Margin="20,20,0,0"/>
        </Grid>
        <ListView Grid.Row="1" x:Name="PDFItemsList" IsItemClickEnabled="False">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="BorderThickness" Value="0,0,0,1" />
                    <Setter Property="BorderBrush" Value="Black"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ContentControl Style="{StaticResource EmptyContentControlStyle}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="{Binding Bill}" Grid.Column="0" Foreground="Black" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding CarrierName}" HorizontalAlignment="Right" Grid.Column="1" Foreground="Black" Grid.Row="1" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding PackageID}" HorizontalAlignment="Right" Foreground="Black" Grid.Column="2" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding Location}" HorizontalAlignment="Right" Foreground="Black" Grid.Column="3" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding ItemType}" HorizontalAlignment="Right" Foreground="Black" Grid.Column="4" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding DeliverTo}" HorizontalAlignment="Right" Foreground="Black" Grid.Column="5" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding Sender}" HorizontalAlignment="Right" Grid.Column="6" Foreground="Black" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding CreationDate}" HorizontalAlignment="Right" Foreground="Black" Grid.Column="7" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding PONumber}" Foreground="Black" HorizontalAlignment="Right" Grid.Column="8" Margin="20,20,0,0"/>
                            <TextBlock Text="{Binding ControlNumber}" HorizontalAlignment="Right" Foreground="Black" Grid.Column="9" Margin="20,20,0,0"/>
                        </Grid>
                    </ContentControl>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Grid>

提前致谢。

【问题讨论】:

  • 请查看官方打印样本Scenario4PageRange
  • 他们在 PageToPrint 框架中使用 RichTextBlock。我的应用程序中没有那个。我有 ListView。
  • 更好的方法是使用rendertargetbitmap将listview做成图片然后打印出来。
  • ListView 可以包含 N 条记录,因此需要相当长的过程和时间。
  • 你需要滚动listview并制作几个targetbitmap然后将targetbitmap拼接在一起。

标签: c# xaml printing uwp


【解决方案1】:

两天后,我现在终于可以做到了。 这是解决方案:

我们需要使用 Linq 使用 'Skip' 和 'Take' 方法,直到我们达到列表的总页数,并且我们需要继续更新列表。总页数取决于 A4 尺寸纸张可容纳的项目数量。在我的情况下是 11。所以我的“分页”事件如下所示:

 protected FrameworkElement firstPage;

 public void PaginateManifestLabel(object sender, PaginateEventArgs e)
    {
        // Clear the cache of preview pages
        printPreviewPages.Clear();

        // Clear the print canvas of preview pages
        PrintCanvas.Children.Clear();

        // This variable keeps track of the last RichTextBlockOverflow element that was added to a page which will be printed
        ListView lastRTBOOnPage = null;

        // 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);

        // We know there are more pages to be added as long as the last RichTextBoxOverflow added to a print preview
        // page has extra content
        int i = 0;
        while (i < _totalPages)
        {


            _manifestPDFDataModelforPriniPagination.ItemsPDFList = tempList.ItemsPDFList.Skip(i * 11).Take(11).ToList();


            lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription);

            i++;
        }



        PrintDocument printDoc = (PrintDocument)sender;

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

AddOnePrintPreviewPage:

private ListView AddOnePrintPreviewPage(ListView lastRTBOAdded, PrintPageDescription printPageDescription)
    {
        // XAML element that is used to represent to "printing page"
        FrameworkElement page;

        // The link container for text overflowing in this page
        ListView textLink;

        // Check if this is the first page ( no previous RichTextBlockOverflow)
        if (lastRTBOAdded == null)
        {
            // If this is the first page add the specific scenario content
            page = firstPage;
        }
        else
        {
            // Flow content (text) from previous pages
            page = new GenericManifestPDF(_manifestPDFDataModelforPriniPagination);
        }
        // Set "paper" width
        page.Width = printPageDescription.PageSize.Width;
        page.Height = printPageDescription.PageSize.Height;
        // Find the last text container and see if the content is overflowing
        textLink = (ListView)page.FindName("PDFItemsList");
        // Add the page to the page preview collection
        printPreviewPages.Add(page);

        return textLink;
    }

GetPreviewPageManifestLabel:

 public void GetPreviewPageManifestLabel(object sender, GetPreviewPageEventArgs e)
    {
        // Provide a UIElement as the print preview.
        PrintDocument printDoc = (PrintDocument)sender;
        printDoc.SetPreviewPage(e.PageNumber, printPreviewPages[e.PageNumber - 1]);
    }

AddPagesManifestLabel:

 public void AddPagesManifestLabel(object sender, AddPagesEventArgs e)
    {
        for (int i = 0; i < printPreviewPages.Count; i++)
        {
            // We should have all pages ready at this point...
            printDoc.AddPage(printPreviewPages[i]);
        }
        PrintDocument printDocument = (PrintDocument)sender;

        // Indicate that all of the print pages have been provided
        printDocument.AddPagesComplete();
    }

PrintTaskRequestedManifestLabel:

public void PrintTaskRequestedManifestLabel(PrintManager sender, PrintTaskRequestedEventArgs args)
    {
        // Create the PrintTask.
        // Defines the title and delegate for PrintTaskSourceRequested
        var printTask = args.Request.CreatePrintTask("Print", PrintTaskSourceRequestedManifestLabel);
        printTask.Options.Orientation = PrintOrientation.Landscape;


        // Handle PrintTask.Completed to catch failed print jobs
        printTask.Completed += PrintTaskCompletedManifestLabel;

    }

PrintTaskSourceRequestedManifestLabel:

public void PrintTaskSourceRequestedManifestLabel(PrintTaskSourceRequestedArgs args)
    {
        // Set the document source.
        args.SetSource(printDocSource);
    }

PrintTaskCompletedManifestLabel:

 public async void PrintTaskCompletedManifestLabel(PrintTask sender, PrintTaskCompletedEventArgs args)
    {
        // Notify the user when the print operation fails.
        if (args.Completion == PrintTaskCompletion.Failed)
        {
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
            {
                ContentDialog noPrintingDialog = new ContentDialog()
                {
                    Title = "Printing error",
                    Content = "\nSorry, failed to print.",
                    PrimaryButtonText = "OK"
                };
                printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
                printDoc.Paginate -= PaginateManifestLabel;
                printDoc.GetPreviewPage -= GetPreviewPageManifestLabel;
                printDoc.AddPages -= AddPagesManifestLabel;
                await noPrintingDialog.ShowAsync();
            });
        }
        else
        {
            printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
        }
    }

准备打印内容:

 public void PreparePrintContent(GenericManifestPDF page)
    {
        firstPage = null;
        if (firstPage == null)
        {
            firstPage = page;
        }
    }

最后你需要像这样调用这些事件:

 if (PrintManager.IsSupported())
                            {
                                printDoc = new PrintDocument();
                                printDocSource = printDoc.DocumentSource;
                                _totalPages = (int)Math.Ceiling(wholeItemsListForPDF.Count / (double)11);
                                tempList = new ManifestPDFDataModel();
                                tempList = _manifestPDFDataModel;
                                printDoc.Paginate += PaginateManifestLabel;
                                printDoc.GetPreviewPage += GetPreviewPageManifestLabel;
                                printDoc.AddPages += AddPagesManifestLabel;
                                printMan = PrintManager.GetForCurrentView();
                                printMan.PrintTaskRequested += PrintTaskRequestedManifestLabel;
                                PreparePrintContent(new GenericManifestPDF(_manifestPDFDataModel));


                                try
                                {
                                    // Show print UI
                                    await PrintManager.ShowPrintUIAsync();
                                }
                                catch (Exception ex)
                                {
                                    // Printing cannot proceed at this time
                                    ContentDialog noPrintingDialog = new ContentDialog()
                                    {
                                        Title = "Printing error",
                                        Content = "\nSorry, printing can' t proceed at this time.",
                                        PrimaryButtonText = "OK"
                                    };
                                    printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
                                    printDoc.Paginate -= PaginateManifestLabel;
                                    printDoc.GetPreviewPage -= GetPreviewPageManifestLabel;
                                    printDoc.AddPages -= AddPagesManifestLabel;

                                    await noPrintingDialog.ShowAsync();
                                }
                            }
                            else
                            {
                                //Printing is not supported on this device
                               ContentDialog noPrintingDialog = new ContentDialog()
                               {
                                   Title = "Printing not supported",
                                   Content = "\nSorry, printing is not supported on this device.",
                                   PrimaryButtonText = "OK"
                               };
                                printMan.PrintTaskRequested -= PrintTaskRequestedManifestLabel;
                                printDoc.Paginate -= PaginateManifestLabel;
                                printDoc.GetPreviewPage -= GetPreviewPageManifestLabel;
                                printDoc.AddPages -= AddPagesManifestLabel;
                                await noPrintingDialog.ShowAsync();

                            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-23
    • 2021-07-18
    • 2023-04-04
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    相关资源
    最近更新 更多