2011-10-28 16 views
6

busqué opciones cómo imprimir controles WPF y encontré algunas soluciones. Necesito ajustar mi control impreso a la página de impresión mientras mantengo la relación de aspecto (mi control es cuadrado, cuadrícula de sudoku).WPF Impresión para ajustar página

Encontré una solución que redimensiona y reposiciona el control para que se ajuste a una página. Eso funciona bien, pero también reposiciona ese control en mi ventana.

aquí es el código que utilizo para la impresión y el escalamiento:

 //get selected printer capabilities 
      System.Printing.PrintCapabilities capabilities = dialog.PrintQueue.GetPrintCapabilities(dialog.PrintTicket); 
     //get scale of the print wrt to screen of WPF visual 
     double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth/mrizka.ActualWidth, capabilities.PageImageableArea.ExtentHeight/mrizka.ActualHeight); 

     //Transform the Visual to scale 
     mrizka.LayoutTransform = new ScaleTransform(scale, scale); 

     //get the size of the printer page 
     Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight); 

     //update the layout of the visual to the printer page size. 
     mrizka.Measure(sz); 
     mrizka.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz)); 

     dialog.PrintVisual(mrizka, mrizka.getID().ToString()); 

probé dos aproaches para resolver este:

  1. Clon mi control y luego transformar clonado uno, unaffecting originales. No funcionó, por alguna razón terminé con una excepción: el DependencyObject provisto no es un contexto para este Freezable, pero extrañamente solo en algunos casos.

  2. Revertir los cambios de tamaño y posición. Intenté llamar al método InvalidateArrange(), que parecía funcionar, pero solo durante la primera llamada del método de impresión. Durante la segunda llamada, no funcionó.

¿Qué debo hacer por favor, cualquier idea < gracias.

Respuesta

19

Sé que esta pregunta es bastante antigua pero estoy buscando una solución a este problema. Aquí está la solución que estoy usando actualmente. Guardo la transformación original contra el elemento de marco y luego vuelvo a aplicarla después de que la impresión haya finalizado.

private void Print(Visual v) 
    { 

     System.Windows.FrameworkElement e = v as System.Windows.FrameworkElement ; 
     if (e == null) 
      return; 

     PrintDialog pd = new PrintDialog(); 
     if (pd.ShowDialog() == true) 
     { 
      //store original scale 
      Transform originalScale = e.LayoutTransform; 
      //get selected printer capabilities 
      System.Printing.PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket); 

      //get scale of the print wrt to screen of WPF visual 
      double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth/e.ActualWidth, capabilities.PageImageableArea.ExtentHeight/
          e.ActualHeight); 

      //Transform the Visual to scale 
      e.LayoutTransform = new ScaleTransform(scale, scale); 

      //get the size of the printer page 
      System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight); 

      //update the layout of the visual to the printer page size. 
      e.Measure(sz); 
      e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz)); 

      //now print the visual to printer to fit on the one page. 
      pd.PrintVisual(v, "My Print"); 

      //apply the original transform. 
      e.LayoutTransform = originalScale; 
     } 
    } 
+1

Deberá agregar referencias a System.Printing y ReachFramework. – StillLearnin

+0

También parece hacer referencia a System.Windows.Media y System.Windows.Controls – Jeff

+2

Esto no funciona correctamente para mí, el LayoutTransform parece ser ignorado sin importar qué tipo de Transform arroje sobre él. – Lennart

1
private void DrawGrap_Click(object sender, RoutedEventArgs e) 
    { 
     // Visual v = sender as Visual; 
     Visual v = song2Grid as Visual; // the object (it is a DataGrid) that you want to print out, not a window 
     PrintDialog prtDlg = new PrintDialog(); 
     if (prtDlg.ShowDialog() == true) 
     { 
      // because 96 pixels in an inch for WPF window 
      double marginLeft = 96.0 * 0.75; // left margin is 0.75 inches 
      double marginTop = 96.0 * 0.75; // top margin is 0.75 inches 
      double marginRight = 96.0 * 0.75; // right margin is 0.75 inches 
      double marginBottom = 96.0 * 0.75; // bottom margin is 0.75 inches 

      // the following steps do not works for a WPF window 
      FrameworkElement win = v as FrameworkElement; 
      Transform oldLayoutTransform = win.LayoutTransform; 
      Size oldSize = new Size(win.ActualWidth, win.ActualHeight); 

      System.Printing.PrintCapabilities pCapability = prtDlg.PrintQueue.GetPrintCapabilities(prtDlg.PrintTicket); 

      // calculate print area that you want 
      double printWidth = (pCapability.PageImageableArea.ExtentWidth - pCapability.PageImageableArea.OriginWidth) 
           - (marginLeft + marginRight); 
      double printHeight = (pCapability.PageImageableArea.ExtentHeight - pCapability.PageImageableArea.OriginHeight) 
       - (marginTop + marginBottom); 

      // calculate the scale 
      double scale = Math.Min(printWidth/oldSize.Width , printHeight/oldSize.Height); 
      if (scale > 1.0) 
      { 
       // keep the original size and layout if printable area is greater than the object being printed 
       scale = 1.0; 
      } 

      // store the original layouttransform 
      win.LayoutTransform = new ScaleTransform(scale, scale); 

      // new size of the visual 
      Size newSize = new Size(oldSize.Width*scale , oldSize.Height*scale); 
      win.Measure(newSize); 

      // centralize print area 
      double xStartPrint = marginLeft + (printWidth - newSize.Width)/2.0; 
      double yStartPrint = marginTop + (printHeight - newSize.Height)/2.0; 
      win.Arrange(new Rect(new Point(xStartPrint,yStartPrint),newSize)); 

      // print out the visual 
      prtDlg.PrintVisual(win as Visual, "PrintTest"); 

      // resotre the original layouttransform and size on screen 
      win.LayoutTransform = oldLayoutTransform; 
      win.Measure(oldSize); 
      win.Arrange(new Rect(new Point(0,0),oldSize)); 
     } 
    } 

era una respuesta a la pregunta que se hizo por user1018711. Ajustar una impresión en una página de la impresora usando C# y WPF. Cuando desee imprimir un visual, que podría ser un control, puede incluir muchos controles (por ejemplo, Button, DataGrid, TextBlock, Label, etc.). Aquí quiero imprimir un DataGrid llamado song2Drid a la impresora pero su contenido era más grande que el tamaño de página de la impresora (su ancho era más ancho que el ancho de un papel) por lo que se truncó. No pude verlos a todos, así que tuve que escalar el visual, pero quería mantener la relación igual que la anterior.

También configuré márgenes de papel a 0.75 pulgadas a cada lado del papel, que quedaron, arriba, derecha e inferior. También centralicé el contenido de visual (song2Grid) en el papel. Así que pude ver el contenido impreso justo en el centro del papel. Pero si el visual era una ventana como Application.Current.MainWindow o cualquier ventana creada programáticamente por una nueva ventana(), entonces no se escalará. significaba que este método no funcionaría para un objeto Window.

Además, si desea recuperar el aspecto original en la pantalla del cambio por escalado para imprimir, entonces tiene que tener las siguientes declaraciones como win.LayoutTransform = oldLayoutTransform; win.Measure (oldSize); win.Arrange (nuevo Rect (new Point (0,0), oldSize));

+4

Agregue un poco de explicación a su respuesta. Solo mostrar el código es muy confuso. –

+0

Utilice el enlace [edit] (http://stackoverflow.com/posts/36967240/edit) para agregar esta información a su respuesta.De esta forma, la gente no tiene que leer todos estos comentarios para encontrar la información que está buscando y mejora enormemente su respuesta. –

+0

Gracias. Soy bastante nuevo aquí. –

Cuestiones relacionadas