2013-10-03 14 views
6

Il mio programma: Contiene un modulo con poche caselle di testo e un pulsante. 'Stampante predefinita' è impostato come Adobe PDF sul mio computer.Stampa di un form/UserControl in C#

Il mio obiettivo: Desidero prendere uno screenshot di un modulo/usercontrol quando l'utente fa clic sul pulsante "Stampa". Lo screenshot viene quindi salvato sul desktop in formato .pdf.

mio problema: Ho seguito due problemi con il codice:

  1. Superficie Screenshot: La dimensione della schermata è troppo grande e non si adatta alle dimensioni della pagina (di default dimensione della pagina) quando stampato/convertito in .pdf. Si prega di fare riferimento alle due immagini qui sotto. Voglio che l'intero screenshot si adatti alla pagina.
  2. Chiede due volte dove convertire e salva: Quando faccio clic sul pulsante "Stampa modulo", i programmi mi chiedono TWICE dove stampare/convertire e salvare il file. Voglio che il programma mi chieda solo una volta, dove stampare e salvare il file.

Problema 1: la schermata catturata dal programma non si adatta alla pagina quando viene stampata. Problem 1: The screenshot captured by the program does not fit the page when printed.

Voglio che l'immagine screenshot per adattarsi come questo su una pagina di .pdf: enter image description here

Codice:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     button1.Text = "Print Form"; 
     button1.Click += new EventHandler(button1_Click); 
     printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage); 
     this.Controls.Add(button1); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     CaptureScreen(); 
     printDocument1.Print(); 
    } 

    Bitmap memoryImage; 

    private void CaptureScreen() 
    { 
     Graphics myGraphics = this.CreateGraphics(); 
     Size s = this.Size; 
     memoryImage = new Bitmap(s.Width, s.Height, myGraphics); 
     Graphics memoryGraphics = Graphics.FromImage(memoryImage); 
     memoryGraphics.CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s); 
    } 

    private void printDocument1_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e) 
    { 
     e.Graphics.DrawImage(memoryImage, 0, 0); 
    } 
} 

Grazie per il vostro aiuto in anticipo. Sono un novizio, sto imparando il linguaggio C# e il tuo aiuto sarà molto apprezzato. :)

+1

Dai un'occhiata a questo Q/A per un campione del ridimensionamento dell'immagine in C#: http://stackoverflow.com/questions/249587 –

+0

Per il secondo problema (doppia finestra di dialogo), questa è solo una supposizione, ma prova a rimuovere questa riga 'printDocument1 .PrintPage + = ... 'dal tuo costruttore. Immagino che ciò avvenga già all'interno di 'InitializeComponent()', il che significa che stai gestendo esplicitamente l'evento due volte. Apri il tuo file Form1.Designer.cs per vedere se ci sono altre cose che stai duplicando. (Ad eccezione della tua chiamata Init, tutto il resto del costruttore potrebbe essere ridondante.) –

+0

@PaulSasik: No. Per il problema 2, rimuovere quella linea mi dà un PDF bianco e non posso salvarlo. ._. – Smith

risposta

3

Ok, check this out, e la modificata printDocument1_PrintPage in particolare:

 private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) 
     { 
      // calculate width and height scalings taking page margins into account 
      var wScale = e.MarginBounds.Width/(float)_memoryImage.Width; 
      var hScale = e.MarginBounds.Height/(float)_memoryImage.Height; 

      // choose the smaller of the two scales 
      var scale = wScale < hScale ? wScale : hScale; 

      // apply scaling to the image 
      e.Graphics.ScaleTransform(scale, scale); 

      // print to default printer's page 
      e.Graphics.DrawImage(_memoryImage, 0, 0); 
     } 

ho spostato tutto l'evento wireup in InitializeComponent dove di solito è dovuto andare, ma è il codice più coinvolta:

using System; 
using System.Drawing; 
using System.Drawing.Printing; 
using System.Windows.Forms; 

namespace testScreenCapScale 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() { InitializeComponent(); } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      CaptureScreen(); 
      printDocument1.Print(); 
     } 

     private Bitmap _memoryImage; 

     private void CaptureScreen() 
     { 
      // put into using construct because Graphics objects do not 
      // get automatically disposed when leaving method scope 
      using (var myGraphics = CreateGraphics()) 
      { 
       var s = Size; 
       _memoryImage = new Bitmap(s.Width, s.Height, myGraphics); 
       using (var memoryGraphics = Graphics.FromImage(_memoryImage)) 
       { 
        memoryGraphics.CopyFromScreen(Location.X, Location.Y, 0, 0, s); 
       } 
      } 
     } 

     private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) 
     { 
      // calculate width and height scalings taking page margins into account 
      var wScale = e.MarginBounds.Width/(float)_memoryImage.Width; 
      var hScale = e.MarginBounds.Height/(float)_memoryImage.Height; 

      // choose the smaller of the two scales 
      var scale = wScale < hScale ? wScale : hScale; 

      // apply scaling to the image 
      e.Graphics.ScaleTransform(scale, scale); 

      // print to default printer's page 
      e.Graphics.DrawImage(_memoryImage, 0, 0); 
     } 
    } 
} 

Form1.Designer.cs

namespace testScreenCapScale 
{ 
    partial class Form1 
    { 
     private System.ComponentModel.IContainer components = null; 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
       components.Dispose(); 
      base.Dispose(disposing); 
     } 

     private void InitializeComponent() 
     { 
      this.printDocument1 = new System.Drawing.Printing.PrintDocument(); 
      this.button1 = new System.Windows.Forms.Button(); 
      this.SuspendLayout(); 
      // 
      // printDocument1 
      // 
      this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage); 
      // 
      // button1 
      // 
      this.button1.Location = new System.Drawing.Point(64, 220); 
      this.button1.Name = "button1"; 
      this.button1.Size = new System.Drawing.Size(75, 23); 
      this.button1.TabIndex = 0; 
      this.button1.Text = "button1"; 
      this.button1.UseVisualStyleBackColor = true; 
      this.button1.Click += new System.EventHandler(this.button1_Click); 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(384, 377); 
      this.Controls.Add(this.button1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 

     } 

     private System.Drawing.Printing.PrintDocument printDocument1; 
     private System.Windows.Forms.Button button1; 
    } 
} 
+0

Grazie mille! Apprezzo il vostro aiuto. Proverò a provarlo. Grazie ancora. :) – Smith

+0

@Smith: Come ho detto, per i principianti (un test rapido) basta copiare e incollare il contenuto del metodo 'printDocument1_PrintPage'. Il ridimensionamento è autonomo e non è necessario modificare altro. È la gestione degli eventi più coinvolgente su cui puoi lavorare separatamente. –

+0

Favoloso! Funziona Paul! Sei fantastico .. grazie ancora .. :) – Smith