2011-06-07 8 views
11

Estoy haciendo algunas impresiones personalizadas usando un PrintDocument en mi aplicación. Tengo un requisito de iniciar sesión cuando nuestros artículos se imprimen con éxito. He conseguido originalmente esto con algo como:Detecta cuando un PrintDocument imprime correctamente (no solo una vista previa)

print_doc.EndPrint += (o,e) => printed_callback(); 

Para hacer mi printed_callback conseguir invoca cuando una impresión acabada. Sin embargo, ahora que estoy agregando soporte de vista previa, estoy pasando un PrintDocument construido exactamente de la misma manera en un PrintPreviewDialog. Si lo hace, se invocará el evento EndPrint después de la representación inicial de la impresión necesaria para la vista previa.

Como resultado, incluso si un usuario hace clic en "Vista previa" y luego simplemente cierra la vista previa, nuestro código de registro se invoca.

¿Alguna sugerencia sobre cómo diferenciar entre una impresión real y una "impresión de vista previa"? Desafortunadamente, no puedo simplemente no conectarme al EndPrint para el PrintDocument pasado al PrintPreviewDialog ya que el usuario puede hacer clic en el botón "Imprimir" en el cuadro de diálogo de vista previa y activar una impresión.

Respuesta

14

Bien, así que logré resolver esto yo mismo, usando la propiedad PrintDocument.PrintController y comprobando la propiedad IsPreview del controlador. Mi última codificado terminó de la siguiente manera:

doc.EndPrint += (o,e) => 
{ 
    if (doc.PrintController.IsPreview) 
     return; 

    print_callback(); 
} 
+1

doble 1, de preguntas y respuestas: -D – peenut

+0

El método anterior es cuando han sido puestos en cola todas las páginas del PrintDocument. No verifica si el trabajo se ha completado. Si desea comprobar cuándo se ha completado el trabajo, consulte [PrintQueue] (https://msdn.microsoft.com/en-us/library/system.printing.printqueue (v = vs.110) .aspx). –

0

yo también arreglé para encontrar una manera diferente que trabajó para mí ...

que tenía una lista de clases MyPrintFileDetail cada uno con un PrintDocument y una StreamReader para dicho documento.

Al configurar mi PrintDocument, agregué un evento PrintPage. En el controlador de eventos PrintPage, identifiqué con qué PrintDocument estaba trabajando al convertir el "remitente" a PrintDocument. Luego, escribí un bucle foreach para identificar el objeto MyPrintFileDetail activo de la lista para obtener el StreamReader que estaba usando para imprimir. Una vez que no hubo más líneas para imprimir, deseché el StreamReader y lo puse en nulo.

Luego, en la devolución de llamada de mi Timer para procesar la lista de objetos MyPrintFileDetail, verifiqué que el StreamReader fuera nulo y, de ser nulo, terminé de imprimir.

Tipo de torpe pero funcionó.

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; 
     } 
    } 
Cuestiones relacionadas