How to use PrintDocument with a scrollable Panel?

二次信任 提交于 2020-01-22 02:48:08

问题


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:

  1. 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).
  2. 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.
  3. 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.
  4. Iterates the ScrollableControl.Controls collection and prints all first-level child controls in their relative position (a child Control's Bounds 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!