UWP 打印预览仅在第一页显示空白页

Posted

技术标签:

【中文标题】UWP 打印预览仅在第一页显示空白页【英文标题】:UWP Print Preview shows blank page only for the first page 【发布时间】:2021-07-18 14:38:20 【问题描述】:

我们目前正在尝试执行一个功能,该功能将在网格视图中打印图像(StorageFile 存储在模型中。)

我们成功地做到了,但我们遇到了一个我无法弄清楚原因的问题:预览的第一页,而且只有预览!,总是空白。打印(或另存为 PDF)时,效果很好。

由于某种原因,打印预览的加载速度似乎比PrintGenerator.xaml 页面中设置的图像更快(我们根据需要使用它来放置图像。)

有人遇到过吗?我尝试了所有我能想到的 Google 搜索,但没有人遇到过这样的问题。

代码:

MainPage.xaml.cs(仅相关行)

private void PrintPages_Click(object sender, RoutedEventArgs e)

    if (CurrentPages.Count == 0)
    
        ShowError(title: "No pages to print", msg: "Please add at least one page to allow printing.");

        return;
    

    // Name: "PrintPages"
    AppBarButton barButton = (AppBarButton)sender;

    barButton.IsEnabled = false;

    PrintImages();

    barButton.IsEnabled = true;

        
private async void PrintImages()

    bottomLoader.Visibility = Visibility.Visible;

    if (PrintManager.IsSupported())
    
        try
        
            await PrintManager.ShowPrintUIAsync();
        
        catch (Exception e)
        
            ShowError(title: "Printing not supported", msg: "Sorry, printing is not supported on this device.\n" + e.Message);
        
    
    else
    
        ShowError(title: "Printing not supported", msg: "Sorry, printing is not supported on this device.");
    

    bottomLoader.Visibility = Visibility.Collapsed;


private PrintManager printManager = PrintManager.GetForCurrentView();

private PrintDocument printDocument = new PrintDocument();

private IPrintDocumentSource printSource;

private List<PrintGenerator> PrintPagePreviews = new List<PrintGenerator>();

private event EventHandler PreviewPagesCreated;

private void RegisterForPrint()

    printManager.PrintTaskRequested += PrintStart;

    printSource = printDocument.DocumentSource;

    printDocument.Paginate += PrintPaginate;
    printDocument.GetPreviewPage += PrintPreview;
    printDocument.AddPages += PrintAddPages;


private void PrintStart(PrintManager sender, PrintTaskRequestedEventArgs e)

    PrintTask task = null;

    task = e.Request.CreatePrintTask("Print", sourceRequestedArgs => 
        IList<string> displayedOptions = task.Options.DisplayedOptions;

        displayedOptions.Clear();
        displayedOptions.Add(StandardPrintTaskOptions.Copies);
        displayedOptions.Add(StandardPrintTaskOptions.Orientation);
        displayedOptions.Add(StandardPrintTaskOptions.MediaSize);
        displayedOptions.Add(StandardPrintTaskOptions.Collation);
        displayedOptions.Add(StandardPrintTaskOptions.Duplex);

        task.Options.MediaSize = PrintMediaSize.NorthAmericaLetter;
        task.Options.PrintQuality = PrintQuality.High;

        task.IsPreviewEnabled = false;
        task.Completed += PrintCompleted;

        sourceRequestedArgs.SetSource(printSource);
    );


private void PrintPaginate(object sender, PaginateEventArgs e)

    lock (PrintPagePreviews)
    
        PrintPagePreviews.Clear();

        PrintPageDescription pageDescription = e.PrintTaskOptions.GetPageDescription(0);

        foreach (AppPage fileToPrint in CurrentPages)
        
            PrintGenerator page = PrintCreatePage(fileToPrint, pageDescription);
            PrintPagePreviews.Add(page);
        

        if (PreviewPagesCreated != null)
        
            PreviewPagesCreated.Invoke(PrintPagePreviews, null);
        

        printDocument.SetPreviewPageCount(PrintPagePreviews.Count, PreviewPageCountType.Intermediate);
    
        

private void PrintAddPages(object sender, AddPagesEventArgs e)

    foreach (PrintGenerator pagePreview in PrintPagePreviews)
    
        printDocument.AddPage(pagePreview);
    

    printDocument.AddPagesComplete();


private PrintGenerator PrintCreatePage(AppPage pageFile, PrintPageDescription pageDescription)

    PrintGenerator page = new PrintGenerator(pageFile.ImageFile);
    Image img = (Image)page.FindName("ImgPreview");

    page.Width = pageDescription.PageSize.Width;
    page.Height = pageDescription.PageSize.Height;

    double marginWidth = (pageDescription.PageSize.Width - pageDescription.ImageableRect.Width);
    double marginHeight = (pageDescription.PageSize.Height - pageDescription.ImageableRect.Height);

    img.Width = page.Width - marginWidth;
    img.Height = page.Height - marginHeight;
    img.Margin = new Thickness()
    
        Top = pageDescription.ImageableRect.Top,
        Left = pageDescription.ImageableRect.Left
    ;

    page.InvalidateMeasure();
    page.UpdateLayout();

    return page;


private void PrintPreview(object sender, GetPreviewPageEventArgs e)

    PrintGenerator printPreview = PrintPagePreviews[e.PageNumber - 1];
    printPreview.UpdateLayout();

    printDocument.SetPreviewPage(e.PageNumber, printPreview);


private void PrintCompleted(PrintTask sender, PrintTaskCompletedEventArgs e)

    if (e.Completion == PrintTaskCompletion.Failed)
    
        ShowError(title: "Printing error", msg: "Sorry, failed to print.");
    
    else if (e.Completion == PrintTaskCompletion.Submitted)
    
        ShowError(title: "Printing success", msg: "Success, task sent to printer.");
    

PrintGenerator.xaml

<Page
    x:Class="COG_ScanDesk.PrintGenerator"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:COG_ScanDesk"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="ThemeResource ApplicationPageBackgroundThemeBrush">

    <Grid>
        <Image x:Name="ImgPreview" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Stretch="Uniform" />
    </Grid>
</Page>

PrintGenerator.xaml.cs

public PrintGenerator(StorageFile file)

    this.InitializeComponent();

    LoadImage(file);


private async void LoadImage(StorageFile file)

    var image = new BitmapImage();
    
    using (var stream = await file.OpenStreamForReadAsync())
    
        await image.SetSourceAsync(stream.AsRandomAccessStream());
    

    this.ImgPreview.Source = image;

【问题讨论】:

【参考方案1】:

由于某种原因,打印预览的加载速度似乎比在 PrintGenerator.xaml 页面中设置的图像要快(我们根据需要使用它来放置图像。)

PrintPreview事件之后看起来LoadImage方法,对于这种情况,我们建议你重新构建布局,如official code sample,如果你确实想使用上面的代码进行打印预览,你可以使任务延迟在PrintPreview 中,如下所示。

private async void PrintPreview(object sender, GetPreviewPageEventArgs e)

    PrintGenerator printPreview = PrintPagePreviews[e.PageNumber - 1];
    await Task.Delay(500);
    printDocument.SetPreviewPage(e.PageNumber, printPreview);

【讨论】:

官方代码是用于带有文本块的画布。这根本不是我们正在做的事情,它适用于所有其他页面和打印本身。 我会尝试延迟。

以上是关于UWP 打印预览仅在第一页显示空白页的主要内容,如果未能解决你的问题,请参考以下文章

打印预览时只有一页,但是打印完之后会自动打多一张空白纸,要怎么设置,才能不打那张空白纸?

在打印预览上能看到只打一页,为啥打出来会有二页呢?而且第二页全部是空白。求大虾们指点。

CSS 打印,仅在第一页宽度 css 上的标题

datalist中有分页,如果在第二页删除一条数据,怎么让它刷新后又回到当前页面

excel打印时第一页无法满页?

如何在SQL Reports中禁止空白页?