C# 如何打印Windows窗体而不显示/显示窗体

C# 如何打印Windows窗体而不显示/显示窗体,c#,.net,winforms,data-binding,printing,C#,.net,Winforms,Data Binding,Printing,我正在尝试自动打印一系列Windows窗体。我不需要给他们看。我在internet上找到的代码示例只有在使用show()显示表单时才起作用!我需要用数据初始化表单并将其发送到打印机这是我正在使用的代码: public partial class Form2_withoutShow : Form{ PrintDocument PrintDoc; Bitmap memImage; public Form2_withoutShow (Data data)

我正在尝试自动打印一系列Windows窗体。我不需要给他们看。我在internet上找到的代码示例只有在使用
show()
显示表单时才起作用!我需要用数据初始化表单并将其发送到打印机这是我正在使用的代码:

public partial class Form2_withoutShow : Form{

     PrintDocument PrintDoc;

     Bitmap memImage;

     public Form2_withoutShow (Data data)
     {

        InitializeComponent();

        /*
           Initialize Data (texboxes, charts ect.) here
       */

        this.PrintDoc = new PrintDocument();
        this.PrintDoc.PrintPage += PrintDoc_PrintPage;
        this.PrintDoc.DefaultPageSettings.Landscape = true;
     }


     public void Print()
     {
        this.PrintDoc.Print();
     }

     void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
     {

        int x = SystemInformation.WorkingArea.X;
        int y = SystemInformation.WorkingArea.Y;
        int width = this.Width;
        int height = this.Height; 

        Rectangle bounds = new Rectangle(x, y, width, height);

        Bitmap img = new Bitmap(width, height); 

        this.DrawToBitmap(img, bounds);
        Point p = new Point(10, 10);

        e.Graphics.DrawImage(img, p);
     }

     private void Form2_withoutShow_Load(object sender, EventArgs e)
     {
         // remove TITLEBar
         this.ControlBox = false;
         this.Text = String.Empty;
     }
}
我从for循环中的另一个类调用
Print()
方法,并通过构造函数传递要初始化的数据


MSDN在屏幕上捕获应显示表单的部分。这对我不管用。如果我不调用
show()。如何在不调用
show()
方法的情况下将数据输入表单?类似于在显示窗体时模拟窗口的方法也不起作用,因为这也是打印结果:最小化窗口。

在显示窗体之前,窗体及其控件未处于状态。要强制创建表单及其控件,只需调用表单的内部方法即可:

var f = new Form1();
var createControl = f.GetType().GetMethod("CreateControl",
                BindingFlags.Instance | BindingFlags.NonPublic);
createControl.Invoke(f, new object[] { true });

var bm = new Bitmap(f.Width, f.Height);
f.DrawToBitmap(bm, new Rectangle(0, 0, bm.Width, bm.Height));
bm.Save(@"d:\bm.bmp");
还要删除表单
Load
事件处理程序中的代码,并将它们放入表单的构造函数中

注意

还有其他解决此问题的方法:

  • 例如,您可以在屏幕边界之外的位置显示表单,然后再次将其隐藏。将
    位置设置为
    (-32000,-32000)
    ,将
    起始位置设置为
    手动
    ,然后
    显示
    隐藏
    在绘制位图之前的表单
  • 或者,作为另一个示例,您可以在将
    Opacity
    设置为
    0
    的情况下显示表单,然后在将表单绘制为位图之前
    show
    Hide

你能解决这个问题吗?不,我没有,我的目标是打印协议,我认为这可以使用填充有数据的gui来完成。我最终用MigraDocs创建了一个PDF,并将其发送到打印机…@ErAcube有答案。你查过了吗?是的谢谢你的指点。我刚刚注意到了这一点。一般来说,使用诸如
RDLC
reports之类的报告工具更能满足这种需求;就像您使用PDF工具所做的,但是报告更友好。无论如何,出于学习的目的,或是为了那些需要通过打印表单来完成任务的案例,我将这个答案与一些工作选项分享。第一个选项是首选。非常感谢您的详细回答。您能否解释一下为什么
createControl
方法必须以
invoke
启动?如果我简单地调用
this.CreateControl()
,则不起作用。欢迎:)您需要的重载是
CreateControl(bool-fignorevible)
,它是内部的,所以即使您想在该形式的构造函数中调用它,也不能。所以使用这个方法的唯一方法就是使用我制作的print方法调用它。它与您的反思方法配合使用。我会用重载来试试。你不能在没有反射的情况下使用重载。如回答中所述,过载是内部的。你做这件事的方式(如答案中所示)是正确的。你不需要改变任何事情。