Winforms – 如何打印整个表单,包括看不见的部分?

我有一个用C#编写的Windows窗体项目。 主窗体上有一个TabControl ,并且要求其中一个用户能够打印其中一个TabPages 。 表格很长,我使用垂直滚动条。 整个表格需要能够打印。

我已经尝试使用DrawToBitmap方法首先转换为位图,但这只包括用户可以看到的表单部分。 我尝试过的其他一些解决方案涉及屏幕捕获,这也有同样的问题。

如何打印或获取整个标签页的图像,包括用户向下滚动时只能看到的部分?

这对于包括TabControlsTabPages在内的任何控件都相当简单,但不包括Forms

您需要做的就是放大相关控件,以显示其所有内容。 (它们不必在屏幕上实际可见 。)

这是一个例子:

 tabControl1.Height = 10080; tabPage2.Height = 10050; dataGridView1.Height = 10000; dataGridView1.Rows.Add(3000); for (int i = 0; i < dataGridView1.Rows.Count; i++) dataGridView1[0, i].Value = i; using (Bitmap bmp = new Bitmap(tabControl1.Width , tabControl1.Height )) { tabControl1.DrawToBitmap(bmp, tabControl1.ClientRectangle); bmp.Save("D:\\xxxx.png", ImageFormat.Png); } 

这样可以保存DataGridViewTabPageTabControl的全部内容。

注意:这不适用于表格,不能超过屏幕尺寸。

更新:这是通过将多个位图拼接在一起来保存具有垂直滚动的表单的代码。 它当然可以扩展到包括水平滚动。 我在这里为大型面板编写了类似的解决方案。

 static void saveLargeForm(Form form, string fileName) { // yes it may take a while form.Cursor = Cursors.WaitCursor; // allocate target bitmap and a buffer bitmap Bitmap target = new Bitmap(form.DisplayRectangle.Width, form.DisplayRectangle.Height); Bitmap buffer = new Bitmap(form.Width, form.Height); // the vertical pointer int y = 0; var vsc = form.VerticalScroll; vsc.Value = 0; form.AutoScrollPosition = new Point(0, 0); // the scroll amount int l = vsc.LargeChange; Rectangle srcRect = ClientBounds(form); Rectangle destRect = Rectangle.Empty; bool done = false; // we'll draw onto the large bitmap with G using (Graphics G = Graphics.FromImage(target)) { while (!done) { destRect = new Rectangle(0, y, srcRect.Width, srcRect.Height); form.DrawToBitmap(buffer, new Rectangle(0, 0, form.Width, form.Height)); G.DrawImage(buffer, destRect, srcRect, GraphicsUnit.Pixel); int v = vsc.Value; vsc.Value = vsc.Value + l; form.AutoScrollPosition = new Point(form.AutoScrollPosition.X, vsc.Value + l); int delta = vsc.Value - v; done = delta < l; y += delta; } destRect = new Rectangle(0, y, srcRect.Width, srcRect.Height); form.DrawToBitmap(buffer, new Rectangle(0, 0, form.Width, form.Height)); G.DrawImage(buffer, destRect, srcRect, GraphicsUnit.Pixel); } // write result to disc and clean up target.Save(fileName, System.Drawing.Imaging.ImageFormat.Png); target.Dispose(); buffer.Dispose(); GC.Collect(); // not sure why, but it helped form.Cursor = Cursors.Default; } 

它使用辅助函数来确定虚拟客户端矩形的净大小,即不包括边框,标题和滚动条:

 static Rectangle ClientBounds(Form f) { Rectangle rc = f.ClientRectangle; Rectangle rb = f.Bounds; int sw = SystemInformation.VerticalScrollBarWidth; var vsc = f.VerticalScroll; int bw = (rb.Width - rc.Width - (vsc.Visible ? sw : 0) ) / 2; int th = (rb.Height - rc.Height) - bw * 2; return new Rectangle(bw, th + bw, rc.Width, rc.Height ); }