You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中能否捕获打印取消事件与打印UI关闭事件及相关需求实现

UWP打印UI关闭提示与事件捕获实现方案

嘿,针对你提到的UWP应用打印需求,我刚好做过类似功能,给你梳理下具体的实现思路和代码示例,完全能满足你的要求:

一、核心结论:后台代码完全可以捕获打印取消与UI关闭事件

UWP的打印API提供了明确的事件和返回值来追踪这些状态,不管是页面后台代码还是ViewModel里都能实现,只要注意线程切换就行(因为部分事件回调会在非UI线程触发)。

二、捕获打印取消操作与UI关闭事件

我们可以结合两个关键点来实现:PrintTask.Completed事件和ShowPrintUIAsync()的返回值,前者追踪打印任务的最终状态,后者判断打印UI的关闭情况。

1. 注册打印任务并绑定Completed事件

首先在页面的导航事件或者初始化方法里注册PrintManager的PrintTaskRequested事件,在这个事件里创建打印任务,并绑定Completed事件来监听任务状态:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    // 获取当前视图的PrintManager实例
    var printManager = PrintManager.GetForCurrentView();
    printManager.PrintTaskRequested += OnPrintTaskRequested;
}

private void OnPrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
    // 创建打印任务
    var printTask = args.Request.CreatePrintTask("我的自定义打印任务", sourceArgs =>
    {
        // 这里设置你的打印内容,比如:
        // sourceArgs.SetSource(printDocumentSource);
        
        // 绑定打印任务完成事件
        printTask.Completed += OnPrintTaskCompleted;
    });
}

private void OnPrintTaskCompleted(PrintTask sender, PrintTaskCompletedEventArgs args)
{
    // 事件回调在非UI线程,需要切换到UI线程更新界面
    _ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        switch (args.Completion)
        {
            case PrintTaskCompletion.Canceled:
                // 这里捕获到打印取消(包括用户点击取消按钮、直接关闭打印UI)
                await new MessageDialog("打印已取消或打印UI已关闭").ShowAsync();
                break;
            case PrintTaskCompletion.Succeeded:
                await new MessageDialog("打印成功完成").ShowAsync();
                break;
            case PrintTaskCompletion.Failed:
                await new MessageDialog("打印失败,请检查打印机状态").ShowAsync();
                break;
        }
    });
}

2. 通过ShowPrintUIAsync()返回值判断UI关闭状态

如果你想在打印UI关闭后立即触发提示,不管打印任务的最终状态,可以直接获取ShowPrintUIAsync()的返回结果:

private async void PrintButton_Click(object sender, RoutedEventArgs e)
{
    try
    {
        var uiCompletionResult = await PrintManager.ShowPrintUIAsync();
        
        // 回到UI线程显示提示
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            switch (uiCompletionResult)
            {
                case PrintUICompletion.Canceled:
                    await new MessageDialog("打印UI已关闭").ShowAsync();
                    break;
                case PrintUICompletion.Completed:
                    await new MessageDialog("打印流程已走完").ShowAsync();
                    break;
                case PrintUICompletion.Failed:
                    await new MessageDialog("打印UI加载失败").ShowAsync();
                    break;
            }
        });
    }
    catch (Exception ex)
    {
        await new MessageDialog($"打印功能异常:{ex.Message}").ShowAsync();
    }
}

三、后台代码(如ViewModel)的实现注意点

如果是在ViewModel这类非UI类里处理,需要注意两个点:

  1. 获取PrintManager时要关联当前视图,确保调用PrintManager.GetForCurrentView()时视图已加载;
  2. 更新UI提示时必须通过UI线程的Dispatcher,避免跨线程异常。

示例ViewModel代码:

using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.Graphics.Printing;

public class PrintViewModel
{
    public async Task TriggerPrint()
    {
        var printManager = PrintManager.GetForCurrentView();
        printManager.PrintTaskRequested += ViewModel_PrintTaskRequested;
        
        var uiResult = await PrintManager.ShowPrintUIAsync();
        
        // 可根据uiResult做额外处理
        printManager.PrintTaskRequested -= ViewModel_PrintTaskRequested; // 记得取消注册避免内存泄漏
    }

    private void ViewModel_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
    {
        var printTask = args.Request.CreatePrintTask("ViewModel打印任务", sourceArgs =>
        {
            // 设置打印源
            printTask.Completed += ViewModel_PrintTaskCompleted;
        });
    }

    private void ViewModel_PrintTaskCompleted(PrintTask sender, PrintTaskCompletedEventArgs args)
    {
        // 用App的Dispatcher切换到UI线程
        _ = App.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            if (args.Completion == PrintTaskCompletion.Canceled)
            {
                await new MessageDialog("打印已取消").ShowAsync();
            }
        });
    }
}

总结

  • 打印UI关闭后显示提示:用ShowPrintUIAsync()的返回值或者PrintTask.Completed事件都能实现;
  • 捕获打印取消操作:通过PrintTask.Completed事件的PrintTaskCompletion.Canceled状态就能精准捕获;
  • 后台代码捕获事件:完全可行,只要处理好线程切换和事件注册/取消的逻辑。

内容的提问来源于stack exchange,提问作者Vijay SathiyaJaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:44:29