如何在使用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
相关产品推荐
相关产品推荐

