2013-10-03 24 views
6

Chương trình của tôi: Chứa biểu mẫu có ít hộp văn bản và một nút. 'Máy in mặc định' được đặt là Adobe PDF trên máy tính của tôi.In biểu mẫu/UserControl trong C#

Mục tiêu của tôi: Muốn chụp ảnh màn hình biểu mẫu/điều khiển người dùng khi người dùng nhấp vào nút 'In'. Ảnh chụp màn hình sau đó được lưu trên màn hình ở định dạng .pdf.

Vấn đề của tôi: Tôi đã sau hai vấn đề với mã:

  1. Kích thước của ảnh chụp màn hình: Kích thước của ảnh chụp màn hình quá lớn và nó không phù hợp với kích thước của trang (mặc định kích thước trang) khi được in/chuyển đổi thành .pdf. Vui lòng tham khảo hai hình ảnh dưới đây. Tôi muốn toàn bộ ảnh chụp màn hình vừa với trang.
  2. Yêu cầu hai lần để chuyển đổi và lưu: Khi tôi nhấp vào nút 'In biểu mẫu', chương trình sẽ hỏi tôi hai lần để in/chuyển đổi và lưu tệp. Tôi muốn chương trình hỏi tôi chỉ một lần, nơi để in và lưu tệp.

Bài toán 1: Ảnh chụp màn hình được chụp bởi chương trình không vừa với trang khi in. Problem 1: The screenshot captured by the program does not fit the page when printed.

Tôi muốn hình ảnh chụp màn hình để phù hợp như thế này trên một trang của .pdf: enter image description here

Code:

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); 
    } 
} 

Nhờ sự giúp đỡ của bạn trước. Tôi là một newbie, học ngôn ngữ C# và sự giúp đỡ của bạn sẽ được nhiều người đánh giá cao. :)

+1

Hãy xem Q/A này để biết ví dụ về tỷ lệ hình ảnh C#: http://stackoverflow.com/questions/249587 –

+0

Đối với vấn đề thứ hai (hộp thoại đôi), đây chỉ là phỏng đoán nhưng hãy thử xóa dòng này 'printDocument1 .PrintPage + = ... 'từ hàm tạo của bạn. Tôi đoán rằng điều này đã xảy ra bên trong 'InitializeComponent()' có nghĩa là bạn đang xử lý một cách rõ ràng sự kiện hai lần. Mở tệp Form1.Designer.cs của bạn để xem liệu có những thứ khác mà bạn đang sao chép hay không. (Ngoại trừ Init của bạn gọi mọi thứ khác trong hàm khởi tạo có thể không cần thiết.) –

+0

@PaulSasik: Không. Đối với vấn đề 2, loại bỏ dòng đó cho tôi một tệp PDF trắng và không thể lưu nó. ._. – Smith

Trả lời

3

Ok, check this out, và sửa đổi printDocument1_PrintPage đặc biệt:

 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); 
     } 

tôi chuyển tất cả các sự kiện wireup vào InitializeComponent nơi nó thường phải đi nhưng nó là mã tham gia nhiều hơn:

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

Cảm ơn rất nhiều! Tôi đánh giá cao sự giúp đỡ của bạn. Tôi sẽ thử và thử nghiệm nó. Cảm ơn một lần nữa. :) – Smith

+0

@Smith: Giống như tôi đã nói, đối với người mới bắt đầu (một bài kiểm tra nhanh) chỉ cần sao chép và dán nội dung của phương thức 'printDocument1_PrintPage'. Việc chia tỷ lệ là khép kín và không có gì khác cần phải thay đổi. Đó là việc xử lý sự kiện có liên quan nhiều hơn đến mức bạn có thể làm việc riêng biệt. –

+0

Tuyệt vời! Nó hoạt động Paul! Bạn là tuyệt vời .. cảm ơn một lần nữa .. :) – Smith