问题
How do I use PrintDocument
with a scrollable panel`?
Here is some of my code:
MemoryImage = new Bitmap(pnl.Width, pnl.Height);
Rectangle rect = new Rectangle(0, 0, pnl.Width, pnl.Height);
pnl.DrawToBitmap(MemoryImage, new Rectangle(0, 0, pnl.Width,
pnl.Height));
Rectangle pagearea = e.PageBounds;
e.Graphics.DrawImage(MemoryImage, (pagearea.Width / 2) -
(pannel.Width / 2), pannel.Location.Y);
回答1:
This is a simplified method to print the content of a ScrollableControl to a Bitmap.
A description of the procedure:
- The control is first scrolled back to the origin (
control.AutoScrollPosition = new Point(0, 0);
(an exception is raised otherwise: the Bitmap has a wrong size. You may want to store the current scroll position and restore it after). - Verifies and stores the actual size of the Container, returned by the PreferredSize property. This property considers the full extent of a container. This will be the size of the Bitmap.
- Calculates the size of the ScrollableControl's ClientArea minus the scrollbars width and height, if any of the scrollbars are visible. The size of the ScrollBars is returned by SystemInformation.VerticalScrollBarWidth and SystemInformation.HorizontalScrollBarHeight. This is the first section that will be printed to the Bitmap.
- Iterates the
ScrollableControl.Controls
collection and prints all first-level child controls in their relative position (a child Control'sBounds
rectangle is relative to the container ClientArea.)
This procedure is by no means perfect. There's no error handling and RichTextBox controls cannot be printed. RichTextBox is a special case, you can see it in the Docs about RichTextBox.DrawToBitmap:
This method is not relevant for this class.
You'ld need to send a EM_FORMATRANGE message to the RichTextBox. In this SO Q/A you can find an implementation.
The ScrollableControlToBitmap()
method takes only a ScrollableControl
as argument: you cannot pass a TextBox control, event if it uses scrollbars.
Set the includeHidden
argument to true
of false
to include or exclude the hidden control.
var bitmap = ScrollableControlToBitmap(this.panel1, false);
public Bitmap ScrollableControlToBitmap(ScrollableControl control, bool includeHidden)
{
if (includeHidden) {
foreach (Control child in control.Controls) {
child.Visible = true;
}
}
control.AutoScrollPosition = new Point(0, 0);
int scrollBarWidth = control.VerticalScroll.Visible
? SystemInformation.VerticalScrollBarWidth : 0;
int scrollBarHeight = control.HorizontalScroll.Visible
? SystemInformation.HorizontalScrollBarHeight : 0;
Size containerSize = control.PreferredSize;
Size noScrollBarsArea = new Size(control.ClientSize.Width - scrollBarWidth,
control.ClientSize.Height - scrollBarWidth);
PointF dpi = PointF.Empty;
using (var g = control.FindForm().CreateGraphics()) {
dpi = new PointF(g.DpiX, g.DpiY);
};
var bitmap = new Bitmap(containerSize.Width, containerSize.Height, PixelFormat.Format32bppArgb);
bitmap.SetResolution(dpi.X, dpi.Y);
control.DrawToBitmap(bitmap, new Rectangle(0, 0, noScrollBarsArea.Width, noScrollBarsArea.Height));
for (int i = control.Controls.Count - 1; i >= 0; i--) {
var child = control.Controls[i];
if (child.Visible) child.DrawToBitmap(bitmap, child.Bounds);
}
return bitmap;
}
This is how it works:
VB.Net version of the same procedure.
来源:https://stackoverflow.com/questions/57247750/how-to-use-printdocument-with-a-scrollable-panel