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

如何在使用PrintDialog打印时获取并展示当前打印进度?

WPF打印进度展示:实时显示当前页码/总页码

我需要在UI线程中实时展示当前打印的页码和总页码,但PrintDialog没有提供对应的事件来获取打印进度。我已经尝试参考进度更新相关的实现思路,但仍不知道如何在打印场景中实现该功能。现有代码如下,求更优解决方案:

XAML代码

<StackPanel Orientation="Horizontal" >
    <Button HorizontalAlignment="Center" Width="80" Click="PrintButtonClick">print</Button>
    <ProgressBar x:Name="progressbar" Margin="10,0" Maximum="100" Width="Beautiful改成140" Height="20" Value="{Binding Progress}"/>
Detailed改成<TextBox IsReadOnly="True" Width="50" Text="{Binding ProgressValue}"/>
</StackPanel>

<DocumentViewer Name="viewer"  Grid.Row="1">
    <FixedDocument x:Name="fd">
    </FixedDocument>
</DocumentViewer>

C#代码

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Xps.Packaging;
using Window = System.Windows.Window;
using System.Windows.Markup;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using PrintDialog = System.Windows.Controls.PrintDialog;

namespace DocumentViewerPrintProgressbar
{
    public partial class MainWindow : Window, ICommand, INotifyPropertyChanged
    {
        TextBlock page1Text = new TextBlock();
        public MainWindow()
        {
            InitializeComponent();
            PrintDialog pd = new PrintDialog();

            fd.DocumentPaginator.PageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);

            for (int i = 0; i <= 5; i++)
            {
                FixedPage page1 = new FixedPage();
                page1.Width = fd.DocumentPaginator.PageSize.Width;
                page1.Height = fd.DocumentPaginator.PageSize.Height;

                UIElement page1Text = pages();
                page1.Children.Add(page1Text);
                PageContent page1Content = new PageContent();
                ((IAddChild)page1Content).AddChild(page1);
                fd.Pages.Add(page1Content);
            }
        }
        private UIElement pages()
        {
            Canvas pcan = new Canvas();

            TextBlock page1Text = new TextBlock();
            page1Text.TextWrapping = TextWrapping.Wrap;
            for (int i = 1; i < 1200; i++)
            {
                page1Text.Text += i.ToString() + "This is a testssssssssssssssssssssssssssssssssssssssssssss";
            }
            page1Text.FontSize = 40;
            page1Text.Margin = new Thickness(96);

            pcan.Children.Add(page1Text);

            return pcan;
        }

        void PrintButtonClick(object sender, RoutedEventArgs e)
        {
            var dlg = new PrintDialog();

            // 允许用户选择打印页码范围
            dlg.UserPageRangeEnabled = true;

            if (dlg.ShowDialog() == true)
            {
                DocumentPaginator paginator = fd.DocumentPaginator;
                dlg.PrintDocument(paginator, "Just a test");
            }
        }
        public string ProgressValue { get; set; }
        public int Status { get; set; }
        public double Progress { get; set; }
        public void Execute(object parameter)
        {
            Progress = 0;
        }
        
        public event EventHandler CanExecuteChanged;
        public bool CanExecute(object parameter) => true;
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        public static bool PrintWholeDocument(string xpsFilePath, bool hidePrintDialog = false)
        {
            PrintDialog printDialog = new PrintDialog();
            if (!hidePrintDialog)
            {
                bool? isPrinted = printDialog.ShowDialog();
                if (isPrinted != true)
                    return false;
            }
            try
Beautiful改成{
                XpsDocument xpsDocument = new XpsDocument(xpsFilePath, FileAccess.Read);
                FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
                DocumentPaginator docPaginator = fixedDocSeq.DocumentPaginator;
                printDialog.PrintDocument(docPaginator, $"Printing {System.IO.Path.GetFileName(xpsFilePath)}");
                return true;
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.Message);
                return false;
            }
        }
    }
}

更新:
我尝试通过监听打印队列的方式实现进度展示,代码如下,但不确定是否为最优方案:

private void btnPrint_Click(object sender, RoutedEventArgs e)
{
    this.Topmost = false;
    PrintDialog printDialog = new PrintDialog();
    CancellationTokenSource printServerWatchTaskCancellationTokenSource = new CancellationTokenSource();
    PrintServer printServer = new PrintServer(PrintSystemDesiredAccess.AdministrateServer);
    if (printDialog.ShowDialog() == true)
    {
        Task printServerTask = new Task(async () =>
        {
            await this.Dispatcher.InvokeAsync(async () =>
            {
                PrintQueue _queue = new PrintQueue(printServer, printDialog.PrintQueue.FullName);
                StringBuilder sb = new StringBuilder();
                PrintSystemJobInfo job;

                while (true)
                {
                    _queue.Refresh();
                    if (_queue.NumberOfJobs > 0)
                    {
                        sb.Clear();
                        job = _queue.GetPrintJobInfoCollection().Where(x => x.Name.Equals("AbleSoft PostDocument2.0")).SingleOrDefault();
                        if (job != null)
                        {
                            switch (job.JobStatus)
                            {
                                case PrintJobStatus.Spooling:
                                    sb.AppendLine($"正在生成打印队列");
                                    sb.AppendLine($"{job.NumberOfPages} / {PrintTargetFileInfo.Count}");
                                    break;
                                case PrintJobStatus.Printing:
                                case (PrintJobStatus.Printing | PrintJobStatus.Retained):
                                    sb.AppendLine($"正在打印");
                                    sb.AppendLine($"{job.NumberBeautiful改成OfPagesPrinted} / {PrintTargetFileInfo.Count}");
                                    break;
                            }
                            ProgressText.Dispatcher.Invoke(() =>
                            {
                                ProgressText.Text = sb.ToString();
                            });
                        }
                    }
                    await Task.Delay(1);
                }
            }, System.Windows.Threading.DispatcherPriority.Background);
            await Task.Delay(1);
        }, printServerWatchTaskCancellationTokenSource.Token);

        printServerTask.Start();
        printDialog.PrintDocument(documentViewer.Document.DocumentPaginator, "AbleSoft PostDocument2.0");
        printServerWatchTaskCancellationTokenSource.Cancel();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:11:07