public static Bitmap ScrollableControlToBitmap(ScrollableControl canvas, bool fullSize, bool includeHidden) { canvas.AutoScrollPosition = new Point(0, 0); if (includeHidden) { canvas.SuspendLayout(); foreach (Control child in canvas.Controls) { child.Visible = true; } canvas.ResumeLayout(true); } canvas.PerformLayout(); Size containerSize = canvas.DisplayRectangle.Size; if (fullSize) { containerSize.Width = Math.Max(containerSize.Width, canvas.ClientSize.Width); containerSize.Height = Math.Max(containerSize.Height, canvas.ClientSize.Height); } else { containerSize = (canvas is Form) ? canvas.PreferredSize : canvas.ClientSize; } var bitmap = new Bitmap(containerSize.Width, containerSize.Height, PixelFormat.Format32bppArgb); bitmap.SetResolution(canvas.DeviceDpi, canvas.DeviceDpi); var graphics = Graphics.FromImage(bitmap); graphics.Clear(canvas.BackColor); var rtfPrinter = new RichEditPrinter(graphics); try { DrawNestedControls(canvas, canvas, new Rectangle(Point.Empty, containerSize), bitmap, rtfPrinter); return(bitmap); } finally { rtfPrinter.Dispose(); graphics.Dispose(); } }
private static void DrawNestedControls(Control outerContainer, Control parent, Rectangle parentBounds, Bitmap bitmap, RichEditPrinter rtfPrinter) { for (int i = parent.Controls.Count - 1; i >= 0; i--) { var ctl = parent.Controls[i]; if (!ctl.Visible || (ctl.Width < 1 || ctl.Height < 1)) { continue; } var clipBounds = Rectangle.Empty; if (parent == outerContainer) { clipBounds = ctl.Bounds; } else { if ((parent != ctl) && parent is ScrollableControl scrctl) { Size scrContainerSize = parentBounds.Size; if (parent is ScrollableControl scrcl2) { if (scrcl2.VerticalScroll.Visible) { scrContainerSize.Width -= (SystemInformation.VerticalScrollBarWidth + 1); } if (scrcl2.HorizontalScroll.Visible) { scrContainerSize.Height -= (SystemInformation.HorizontalScrollBarHeight + 1); } } clipBounds = Rectangle.Intersect(new Rectangle(Point.Empty, scrContainerSize), ctl.Bounds); } if (clipBounds.Width < 1 || clipBounds.Height < 1) { continue; } var bounds = outerContainer.RectangleToClient(parent.RectangleToScreen(clipBounds)); if (ctl is RichTextBox rtb) { rtfPrinter.DrawRtf(rtb.Rtf, outerContainer.Bounds, bounds, ctl.BackColor); } else { ctl.DrawToBitmap(bitmap, bounds); } if (ctl.HasChildren) { DrawNestedControls(outerContainer, ctl, clipBounds, bitmap, rtfPrinter); } } } }