【问题标题】:Printing a Form/UserControl in C#在 C# 中打印表单/用户控件
【发布时间】:2013-10-10 12:16:47
【问题描述】:

我的程序: 包含一个带有几个文本框和一个按钮的表单。 “默认打印机”在我的计算机上设置为 Adobe PDF

我的目标:想要在用户单击“打印”按钮时截取表单/用户控件的屏幕截图。然后屏幕截图以 .pdf 格式保存在桌面上。

我的问题:我的代码有以下两个问题:

  1. 屏幕截图尺寸:屏幕截图的尺寸太大,打印/转换为.pdf时不适合页面尺寸(默认页面尺寸)。请参考下面的两张图片。我希望整个屏幕截图适合页面。
  2. 询问两次转换和保存位置: 当我点击“打印表单”按钮时,程序两次询问我在哪里打印/转换和保存文件。我希望程序只问我一次,在哪里打印和保存文件。

问题1:程序截取的截图在打印时不适合页面。

我希望屏幕截图像​​这样适合 .pdf 的一页:

代码:

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

提前感谢您的帮助。我是新手,正在学习 c# 语言,非常感谢您的帮助。 :)

【问题讨论】:

  • 看看这个 Q/A 以获得 C# 图像缩放的示例:stackoverflow.com/questions/249587
  • 对于第二期(双对话),这只是一个猜测,但请尝试从您的构造函数中删除这一行 printDocument1.PrintPage += ...。我猜这已经发生在InitializeComponent() 内部,这意味着您明确地处理了两次事件。打开您的 Form1.Designer.cs 文件以查看您是否正在复制其他内容。 (除了您的 Init 调用之外,构造函数中的其他所有内容都可能是多余的。)
  • @PaulSasik:不。对于问题 2,删除该行会给我一个白色的 PDF,并且无法保存。 ._.
  • 在下面查看我的答案。对于初学者,只需从类中复制/粘贴 printDocument1_PrintPage 方法。要处理您的双重保存对话框,请查看整个代码。 (事件通常在与表单关联的 Designer 类文件中进行管理。)

标签: c# winforms visual-studio-2010 pdf printing


【解决方案1】:

好的,看看这个,特别是修改后的printDocument1_PrintPage

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

我将所有事件连线移动到通常应该去的 InitializeComponent 中,但它涉及的代码更多:

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

【讨论】:

  • 非常感谢!我感谢您的帮助。我会尝试测试它。再次感谢。 :)
  • @Smith:就像我说的,对于初学者(快速测试),只需复制并粘贴 printDocument1_PrintPage 方法的内容即可。缩放是独立的,无需更改任何其他内容。您可以单独处理更多涉及的事件处理。
猜你喜欢
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多