自定义打印预览 UI

本主题介绍如何自定义打印预览 UI 中的打印选项和设置。 有关打印的详细信息,请参阅 从应用打印。

自定义打印选项

默认情况下,打印预览 UI 显示 ColorMode副本方向打印选项。 除了这些选项,还可以向打印预览 UI 添加其他几个常见的打印机选项:

这些选项在 StandardPrintTaskOptions 类中定义。 可以在打印预览 UI 中显示的选项列表中添加或删除选项。 还可以更改显示的顺序,并设置向用户显示的默认设置。

但是,以这种方式所做的修改仅影响打印预览 UI。 用户始终可以通过点击 打印预览 UI 中的“更多”设置来访问打印机支持的所有选项

定义要显示的选项

注册应用进行打印时(请参阅 “从应用打印”),该注册的一部分包括定义 PrintTaskRequested 事件处理程序。 用于自定义打印预览 UI 中显示的选项的代码将添加到 PrintTaskRequested 事件处理程序中。

PrintTaskRequested 事件处理程序中创建 PrintTask 后,可以获取 DisplayedOptions 列表,其中包含打印预览 UI 中显示的选项项。 可以通过插入、追加、删除或重新排序选项来修改此列表。

注意

尽管你的应用可以指定要显示的任何打印选项,但只有所选打印机支持的选项才会显示在打印预览 UI 中。 打印 UI 不会显示所选打印机不支持的选项。

private void PrintTask_Requested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
    // Create the PrintTask.
    // Defines the title and delegate for PrintTaskSourceRequested.
    PrintTask printTask = args.Request.CreatePrintTask("WinUI 3 Printing example", PrintTaskSourceRequested);

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

    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        InvokePrintingButton.IsEnabled = false;
    });

    // Customize options displayed in print preview UI.
    // Get the list of displayed options.
    IList<string> displayedOptions = printTask.Options.DisplayedOptions;

    // Choose the printer options to be shown.
    // The order in which the options are appended determines
    // the order in which they appear in the UI.
    displayedOptions.Clear();
    displayedOptions.Add(StandardPrintTaskOptions.Copies);
    displayedOptions.Add(StandardPrintTaskOptions.Orientation);
    displayedOptions.Add(StandardPrintTaskOptions.MediaSize);
    displayedOptions.Add(StandardPrintTaskOptions.Collation);
    displayedOptions.Add(StandardPrintTaskOptions.Duplex);

    // Preset the default value of the print media size option.
    printTask.Options.MediaSize = PrintMediaSize.NorthAmericaLegal;
}

指定默认选项

还可以在打印预览 UI 中设置选项的默认值。 上一个示例中的以下代码行设置 MediaSize 选项的默认值。

// Preset the default value of the print media size option.
printTask.Options.MediaSize = PrintMediaSize.NorthAmericaLegal;

注意

在 DisplayedOptions 列表中设置值时,可以使用从 StandardPrintTaskOptions 获取的名称(例如 StandardPrintTaskOptions.MediaSize)。

设置选项的默认值时,可以使用 PrintTaskOptions (例如 PrintTaskOptions.MediaSize)。

添加自定义打印选项

在这里,我们演示如何创建新的自定义打印选项、定义选项支持的值列表,然后将该选项添加到打印预览。 在此示例中,自定义打印选项允许用户指定是仅打印页面上的文本、仅打印图像还是同时打印文本和图像。 这些选项显示在下拉列表中。

为了确保良好的用户体验,系统要求应用在 PrintTaskRequestedEventArgs.Request.Deadline 指定的时间内处理 PrintTaskRequested 事件。 因此,我们仅使用 PrintTaskRequested 处理程序来创建打印任务。 请求打印文档源时,可以完成打印设置自定义。 在这里,我们使用 lambda 表达式 来定义 PrintTaskSourceRequestedHandler 内联,从而更轻松地访问 PrintTask。

首先,获取 PrintTaskOptionDetails 对象及其 DisplayedOptions 列表。 使用此选项将新的打印选项添加到打印预览 UI。

接下来,若要在下拉列表中显示自定义打印选项,请调用 PrintTaskOptionDetails.CreateItemListOption 以创建 PrintCustomItemListOptionDetails 对象。 创建新的打印选项并初始化选项值列表。 最后,将新选项添加到 DisplayedOptions 列表,并为 OptionChanged 事件分配处理程序。 由于您只是在默认选项列表末尾添加新的打印选项,因此无需清除 DisplayedOptions 列表;只需添加新选项。

private void PrintTask_Requested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
    // Create the PrintTask.
    PrintTask printTask = null;
    printTask = args.Request.CreatePrintTask("WinUI 3 Printing example", sourceRequestedArgs =>
    {
        PrintTaskSourceRequestedDeferral deferral = 
            sourceRequestedArgs.GetDeferral();
        PrintTaskOptionDetails printDetailedOptions = 
            PrintTaskOptionDetails.GetFromPrintTaskOptions(printTask.Options);
        IList<string> displayedOptions = printDetailedOptions.DisplayedOptions;

        // Create a new list option.
        PrintCustomItemListOptionDetails pageFormat =
            printDetailedOptions.CreateItemListOption("PageContent", "Page content");
        pageFormat.AddItem("PicturesText", "Pictures and text");
        pageFormat.AddItem("PicturesOnly", "Pictures only");
        pageFormat.AddItem("TextOnly", "Text only");

        // Add the custom option to the option list
        displayedOptions.Add("PageContent");

        printDetailedOptions.OptionChanged += PrintDetailedOptions_OptionChanged;
        sourceRequestedArgs.SetSource(printDocumentSource);

        deferral.Complete();
    });

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

    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        InvokePrintingButton.IsEnabled = false;
    });
}

这些选项以追加的相同顺序显示在打印预览 UI 中,其中第一个选项显示在窗口顶部。 在此示例中,将最后追加自定义选项,使其显示在选项列表的底部。 但是,可以将它放在列表中的任意位置:不需要最后添加自定义打印选项。

当用户更改自定义选项中的所选选项时,请使用所选选项更新打印预览图像。 更新打印预览版后,调用 InvalidatePreview 方法在打印预览 UI 中重新绘制图像,如下所示。

void PrintDetailedOptions_OptionChanged(PrintTaskOptionDetails sender, 
                                        PrintTaskOptionChangedEventArgs args)
{
    string optionId = args.OptionId as string;
    if (string.IsNullOrEmpty(optionId))
    {
        return;
    }

    if (optionId == "PageContent")
    {
        PrintCustomItemListOptionDetails pageContentOption =
            (PrintCustomItemListOptionDetails)sender.Options["PageContent"];
        string pageContentValue = pageContentOption.Value.ToString();

        if (pageContentValue == "PicturesOnly")
        {
            pageLayoutOption = PageLayoutOption.Images;
        }
        else if (pageContentValue == "TextOnly")
        {
            pageLayoutOption = PageLayoutOption.Text;
        }
        else
        {
            pageLayoutOption = PageLayoutOption.TextAndImages;
        }

        DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
        {
            printDocument.InvalidatePreview();
        });
    }
}

若要支持使用页面中的自定义选项,请为可用选项和页面级变量添加枚举来保存所选选项。

internal enum PageLayoutOption : int
{
    Text = 1,
    Images = 2,
    TextAndImages = 3
}

PageLayoutOption pageLayoutOption = PageLayoutOption.TextAndImages;

然后,在 Paginate 处理程序中使用所选选项,在该处理程序中添加打印预览的内容。

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

    // Get the PrintTaskOptions.
    PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);
    // Get the page description to determine the size of the print page.
    PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);

    // Create the print layout.
    StackPanel printLayout = new StackPanel();
    printLayout.Width = pageDescription.PageSize.Width;
    printLayout.Height = pageDescription.PageSize.Height;
    printLayout.BorderBrush = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.DimGray);
    printLayout.BorderThickness = new Thickness(48);

    // Use the custom print layout options to determine
    // which elements to add to the print page. 
    if (pageLayoutOption == PageLayoutOption.Images ||
        pageLayoutOption == PageLayoutOption.TextAndImages)
    {
        Image printImage = new Image();
        printImage.Source = printContent.Source;

        printImage.Width = pageDescription.PageSize.Width / 2;
        printImage.Height = pageDescription.PageSize.Height / 2;
        printLayout.Children.Add(printImage);
    }

    if (pageLayoutOption == PageLayoutOption.Text ||
        pageLayoutOption == PageLayoutOption.TextAndImages)
    {
        TextBlock imageDescriptionText = new TextBlock();
        imageDescriptionText.Text = imageDescription.Text;
        imageDescriptionText.FontSize = 24;
        imageDescriptionText.HorizontalAlignment = HorizontalAlignment.Center;
        imageDescriptionText.Width = pageDescription.PageSize.Width / 2;
        imageDescriptionText.TextWrapping = TextWrapping.WrapWholeWords;

        printLayout.Children.Add(imageDescriptionText);
    }

    // Add the print layout to the list of preview pages.
    printPreviewPages.Add(printLayout);

    // Report the number of preview pages created.
    PrintDocument printDocument = (PrintDocument)sender;
    printDocument.SetPreviewPageCount(printPreviewPages.Count,
                                          PreviewPageCountType.Intermediate);
}

另请参阅