2011-10-28 13 views
6

Ho cercato le opzioni su come stampare i controlli WPF e ho trovato alcune soluzioni. Ho bisogno di adattare il mio controllo stampato alla pagina di stampa preservando le proporzioni (il mio controllo è quadrato, griglia sudoku).WPF Stampa per adattarsi alla pagina

Ho trovato una soluzione che ridimensiona e il controllo delle reposizioni per adattarsi a una pagina. Funziona bene, ma anche le riposizionazioni che controllano sulla mia finestra.

qui è il codice che uso per la stampa e il ridimensionamento:

 //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()); 

Ho provato due aproaches per risolvere questo:

  1. Clone mio controllo e poi trasformare clonato uno, originale unaffecting. Non funzionava, per qualche motivo ho finito con un'eccezione: il DependencyObject fornito non è un contesto per questo Freezable, ma stranamente solo in alcuni casi.

  2. Dimensioni e cambi di posizione. Ho provato a chiamare il metodo InvalidateArrange(), che sembrava funzionare, ma solo durante la prima chiamata del metodo di stampa. Durante la seconda chiamata, non ha funzionato.

Cosa devo fare per favore, qualsiasi idea < grazie.

risposta

19

So che questa domanda è piuttosto vecchia ma alla ricerca di una soluzione a questo problema. Ecco la soluzione che sto attualmente utilizzando. Conservo la trasformazione originale rispetto all'elemento framework e poi riapplica dopo che la stampa è terminata.

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

Sarà necessario aggiungere riferimenti a System.Printing e ReachFramework. – StillLearnin

+0

Sembra anche fare riferimento a System.Windows.Media e System.Windows.Controls – Jeff

+2

Questo non funziona correttamente per me, il LayoutTransform sembra essere ignorato, non importa che tipo di Transform mi passi. – 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)); 
     } 
    } 

E 'stata una risposta alla domanda che è stato chiesto da user1018711. Stampa di una stampa su una pagina della stampante usando C# e WPF. Quando si desidera stampare un'immagine, che potrebbe essere un controllo che potrebbe includere molti controlli (ad esempio Button, DataGrid, TextBlock, Label ed ecc.). Qui voglio stampare un DataGrid chiamato song2Drid sulla stampante, ma il suo contenuto era più grande della pagina della stampante (la sua larghezza era più larga della larghezza di un foglio), quindi è stato troncato. Non sono riuscito a vederli tutti, quindi ho dovuto ridimensionare il visual ma volevo mantenere il rapporto uguale a quello vecchio.

Ho anche impostato i margini della carta su 0,75 pollici su ciascun lato della carta, che sono rimasti, in alto, a destra e in basso. Ho anche centralizzato il contenuto di visual (song2Grid) sulla carta. Così ho potuto vedere il contenuto stampato proprio al centro del foglio. Ma se l'elemento visivo era una finestra come Application.Current.MainWindow o qualsiasi finestra creata a livello di programmazione da una nuova finestra(), quindi non verrà ridimensionata. significava che questo metodo non funzionerebbe per un oggetto Window.

Inoltre, se si desidera ripristinare l'aspetto originale sullo schermo da quello modificato mediante il ridimensionamento per stampare, è necessario disporre delle istruzioni come segue win.LayoutTransform = oldLayoutTransform; win.Measure (oldSize); win.Arrange (new Rect (new Point (0,0), oldSize));

+4

Aggiungi qualche spiegazione alla tua risposta. Solo mostrare codice è molto confuso. –

+0

Utilizzare il collegamento [modifica] (http://stackoverflow.com/posts/36967240/edit) per aggiungere queste informazioni alla risposta.In questo modo le persone non devono leggere tutti questi commenti per trovare le informazioni che stanno cercando e migliora notevolmente la risposta. –

+0

Grazie. Sono abbastanza nuovo qui. –

Problemi correlati