问题
please i have a scrollable panel of which some of the content are hidden and other are visible on the form, my worry is how to print all the content on the panel including the hidden ones. How possible could i be help
Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Panel1.AutoSize = True
Dim b As New Bitmap(Panel1.DisplayRectangle.Width, Panel1.DisplayRectangle.Height)
Panel1.DrawToBitmap(b, Panel1.ClientRectangle)
e.Graphics.DrawImage(b, New Point(40, 40))
Panel1.AutoSize = False
End Sub
回答1:
To print the content of a ScrollableControl to a Bitmap, we have to consider its PreferredSize instead of its ClientRectangle. The PreferredSize
property returns the internal bounds of the ScrollableControl
- the area that its child controls occupy - then print each child control outside the visible bounds on its own.
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 doesn't handle RichTextBox controls. RichTextBox is a special case, it doesn't print its content. As a workaround, we can send a EM_FORMATRANGE message to the control.
You can find an implementation in this SO Q/A .
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.
Print the content of a Panel to a Bitmap, including the hidden controls:
Dim bitmap = ScrollableControlToBitmap(Me.Panel1, True)
Imports System.Drawing.Imaging
Public Function ScrollableControlToBitmap(control As ScrollableControl, includeHidden As Boolean) As Bitmap
If includeHidden Then
For Each child As Control In control.Controls
child.Visible = True
Next
End If
control.AutoScrollPosition = New Point(0, 0)
Dim scrollBarWidth As Integer =
If(control.VerticalScroll.Visible, SystemInformation.VerticalScrollBarWidth, 0)
Dim scrollBarHeight As Integer =
If(control.HorizontalScroll.Visible, SystemInformation.HorizontalScrollBarHeight, 0)
Dim containerSize As Size = control.PreferredSize
Dim noScrollBarsArea As New Size(control.ClientSize.Width - scrollBarWidth, control.ClientSize.Height - scrollBarWidth)
Dim dpi As PointF = PointF.Empty
Using g As Graphics = control.FindForm().CreateGraphics()
dpi = New PointF(g.DpiX, g.DpiY)
End Using
Dim bmp As Bitmap = New Bitmap(containerSize.Width, containerSize.Height, PixelFormat.Format32bppArgb)
bmp.SetResolution(dpi.X, dpi.Y)
control.DrawToBitmap(bmp, New Rectangle(0, 0, noScrollBarsArea.Width, noScrollBarsArea.Height))
For i As Integer = control.Controls.Count - 1 To 0 Step -1
Dim child As Control = control.Controls(i)
If child.Visible Then child.DrawToBitmap(bmp, child.Bounds)
Next
Return bmp
End Function
This is how it works:
C# version of the same procedure.
来源:https://stackoverflow.com/questions/57298676/how-to-print-hidden-and-visible-content-on-a-panel-when-scroll-using-vb-net