#c# #.net #winforms #printing
#c# #.net #winforms #печать
Вопрос:
Я выполняю некоторую пользовательскую печать, используя PrintDocument в моем приложении. У меня есть требование регистрировать, когда наши элементы успешно напечатаны. Изначально я достиг этого с помощью чего-то вроде:
print_doc.EndPrint = (o,e) => printed_callback ();
Чтобы мой printed_callback
вызывался по завершении печати. Однако теперь, когда я добавляю поддержку предварительного просмотра, я передаю PrintDocument
созданный точно таким же образом файл в PrintPreviewDialog. Это приводит к тому, что EndPrint
событие вызывается после первоначального рендеринга распечатки, необходимой для предварительного просмотра.
В результате, даже если пользователь нажимает «Предварительный просмотр», а затем просто закрывает предварительный просмотр, вызывается наш код протоколирования.
Есть предложения о том, как отличить реальную распечатку от «предварительной печати»? К сожалению, я не могу просто не подключиться к EndPrint
для PrintDocument
передачи PrintPreviewDialog
, поскольку пользователь может нажать кнопку «Печать» в диалоговом окне предварительного просмотра и запустить распечатку.
Ответ №1:
Хорошо, итак, мне действительно удалось выяснить это самостоятельно, используя PrintDocument . Свойство PrintController и проверка IsPreview
свойства контроллера. Мой окончательный кодированный результат выглядел следующим образом:
doc.EndPrint = (o,e) =>
{
if (doc.PrintController.IsPreview)
return;
print_callback ();
}
Комментарии:
1. дважды 1 для вопроса и ответа 😀
2. Описанный выше метод применяется, когда все страницы в документе PrintDocument загружены в буфер. Он не проверяет, завершено ли задание. Если вы хотите проверить, когда задание завершено, вместо этого посмотрите на PrintQueue .
Ответ №2:
Мне тоже удалось найти другой способ, который сработал для меня…
У меня был список классов MyPrintFileDetail, каждый из которых содержал PrintDocument и StreamReader для указанного документа.
При настройке моего PrintDocument я добавил событие PrintPage. В обработчике событий PrintPage я определил, с каким документом PrintDocument я работал, путем приведения «отправителя» к документу PrintDocument. Затем написал цикл foreach для определения рабочего объекта MyPrintFileDetail из списка, чтобы получить StreamReader, который я использовал для печати. Как только больше не осталось строк для печати, я удалил StreamReader и установил для него значение null.
Затем в моем обратном вызове таймера для обработки списка объектов MyPrintFileDetail я проверил StreamReader на null, и если null, я закончил печать.
Немного неуклюже, но это сработало.
private void PD_PrintPage(object sender, PrintPageEventArgs e)
{
PrintDocument p = (PrintDocument)sender;
PrintFileDetail pfdWorkingOn = null;
foreach (PrintFileDetail pfd in pfds)
{
if (pfd._PrintDoc.DocumentName == p.DocumentName)
{
pfdWorkingOn = pfd;
break;
}
}
float yPos = 0f;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
string line = null;
float linesPerPage = e.MarginBounds.Height / _TextFilePrintingFont.GetHeight(e.Graphics);
while (count < linesPerPage)
{
line = pfdWorkingOn._TxtFileBeingPrinted.ReadLine();
if (line == null)
{
break;
}
yPos = topMargin count * _TextFilePrintingFont.GetHeight(e.Graphics);
e.Graphics.DrawString(line, _TextFilePrintingFont, Brushes.Black, leftMargin, yPos, new StringFormat());
count ;
}
if (line != null)
{
e.HasMorePages = true;
}
else
{
pfdWorkingOn._TxtFileBeingPrinted.Dispose();
pfdWorkingOn._TxtFileBeingPrinted = null;
}
}