|
 |
 |
| Basic Questions. How do I ... ?
- Add PrintForm to the Visual Studio
Toolbox?
- Print a Form with one line of code?
- PrintPreview a Form with one line
of code?
- Change the Background color
of the Form on the printout?
- Prevent Form controls from showing
up on the printout?
- Center the printed Form in the
page?
- Zoom the Form to fill the printed page?
- Add headers and footers to my printout?
- Set margin sizes on my printout?
Advanced Questions. How do I ... ?
- Turn printing of the borders of my
Form / control on or off?
- Print different controls from
a single Form (e.g. Tab pages) on each page of the printout?
- Print different Forms on each
page of the printout?
- Print a Form which is larger than
the paper size over multiple pages?
- Print a control inside a UserControl
with a different BackColor?
- Set UseLegacyPrinting, BackColorWhilePrinting,
VisibleWhilePrinting settings on controls that are inside a UserControl?
- Print more than one Form / container
control (tab, panel etc) on the same page?
- Print the Page image to a file?
- Print multiple Page images to
a TIFF file?
- Print a Form or control scaled to custom
size?
- Print without showing the 'Printing
Page n' dialog?
- Print a hidden Form / control?
- Handle rendering of a legacy control
myself?
|
| |
 Basic
Questions. How do I ... ? |
| Q: Add
PrintForm to the Visual Studio Toolbox? |
| A:
After you have installed the PrintForm component you
will need to add it to your toolbox so that you can
then drop it onto your Form. The following procedure
describes how to do this:
- Open the Visual Studio .NET editor.
- Right click on the 'General' tab of the Toolbox,
and select 'Customize Toolbox...' ('Add/Remove Items...'
in Visual Studio 2003). You may alternatively add
it to the Windows Forms tab, or create a new tab.
- Select the .NET Framework Components tab of the
Customize Toolbox Dialog and scroll down until you
find 'PrintForm'; check this and click OK.
You should now be able to drag a PrintForm component
from the General Tab of the Toolbox onto your Form's
Component tray.
|
|
|
| Q: Print
a Form with one line of code? |
| A:
Perform the following steps:
- Drag a PrintForm component onto your Form from
the Visual Studio Toolbox
- Set the PrintForm.BodyContainer
property to reference your Form
- Add a button and button click handler. In the handler
call PrintForm.Print()
|
|
|
| Q: PrintPreview
a Form with one line of code? |
| A:
Perform the following steps:
- Drag a PrintForm component onto your Form from
the Visual Studio Toolbox
- Set the PrintForm.BodyContainer
property to reference your Form
- Drag a PrintPreviewDialog component onto your Form
from the Visual Studio Toolbox
- Set the PrintPreviewDialog.Document
property to reference the PrintForm component
- Add a button and button click handler. In the handler
call PrintPreviewDialog.ShowDialog()
|
|
|
| Q: Change
the Background color of the Form on the printout? |
| A:
PrintForm extends each control on your Form, and the
Form itself, with a new property: BackColorWhilePrinting.
You can set this for each control on the Form, but since
as a general rule child controls inherit their parent's
BackColor it is usually enough to set the Form's BackColorWhilePrinting
property (e.g. to White) and all the child controls
on the Form will pick this up automatically. |
|
|
| Q: Prevent
Form controls from showing up on the printout? |
| A:
PrintForm extends each control on your Form with a new
property: VisibleWhilePrinting. You
can set this for each control on the Form to prevent
it from being rendered in the printout, for example
you may not want the OK and Cancel buttons to appear
on the printout. |
|
|
| Q: Center
the printed Form in the page? |
| A:
The PrintForm.CenterStyle property
allows you to center the printed output in the horizontal
or vertical dimension, or both. When the Form or control
you are printing is smaller than the Margins of the
printed page, PrintForm uses the CentreStyle setting
to center the output, alternatively to print the output
at the top left of the Margin rectangle set CenterStyle
= CenterStyle.None.
The following diagrams illustrate the effects of different
CenterStyle options:
 
 
|
|
|
| Q: Zoom
the Form to fill the printed page? |
| A:
PrintForm can automatically scale the printed output
it produces to allow a large Form to fit onto a single
printed page. Setting the AutoFit property
to one of the following values controls this behavior:
PageElement.None: When AutoFit is
set to PageElement.None the output is scaled according
to the setting of the PrintForm.ManualZoom
PageElement.Body: Zooming is applied
to the BodyContainer page element only. HeaderContainer
and FooterContainer contents will remain at the default
scale factor of 1.0
PageElement.All: Zooming is applied
to the BodyContainer, HeaderContainer and FooterContainer
page elements equally, based on the scaling necessary
to fit the BodyContainer contents into the MarginBounds
rectangle.
|
|
|
| Q: Add
headers and footers to my printout? |
| A:
PrintForm has three properties that can be set to point
at individual controls: HeaderContainer,
BodyContainer and FooterContainer.
The contents of the control referenced in the BodyContainer
property are rendered inside the Margin rectangle on
the page, the HeaderContainer and FooterContainer (if
specified) are rendered directly above and directly
beneath the Margin rectangle respectively.

So to produce a printout of your Form with headers
and footers present, add two extra Panels to the Form.
Inside these add the controls you wish to appear as
your header and footer. Set HeaderContainer to the header
panel, BodyContainer to the Form and FooterContainer
to the footer panel. Finally, make sure they are not
visible on the surface of the Form by setting their
Location to (-1000, -1000).
|
|
|
| Q: Set
margin sizes on my printout? |
|
A: Margin
widths are controlled by the Margins property
of the PageSettings object.
There are two ways to set this: 1) set the PrintDocument.DefaultPageSettings.Margins
property to control the default margin size of all pages
printed by the PrintDocument, or 2) set e.PageSettings.Margins
in the PrintDocument.QueryPageSettings event
to set each printed page's Margin size individually:
1) Setting the default size for all pages in the form
Load event via the DefaultPageSettings property:
Private Sub frmSimpleForm_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim newMargins As System.Drawing.Printing.Margins newMargins = New System.Drawing.Printing.Margins(50, 50, 50, 50) Me.PrintForm1.DefaultPageSettings.Margins = newMargins End Sub
2) Setting each page's Margin size individually via
the QueryPageSettingsEventArgs.PageSettings property
in the QueryPageSettings event:
Private Sub PrintForm1_QueryPageSettings(ByVal sender As Object, _ ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) Handles PrintForm1.QueryPageSettings Dim newMargins As System.Drawing.Printing.Margins newMargins = New System.Drawing.Printing.Margins(50, 50, 50, 50) e.PageSettings.Margins = newMargins End Sub
|
|
|
|
 Advanced
Questions. How do I ... ? |
| Q: Turn
printing of the borders of my Form / control on or off? |
| A:
The borders, or non-client area, of the outermost control
you are rendering can be turned on or off using the
PrintForm.PrintBorders property.
For example if you are printing a Form in a report
style document you may not want the Form title bar and
border to be printed, in this case you would set PrintBorders
= None. Alternatively you may be printing
a 'screen shot' style representation of a Form where
you want the title bar and border to be shown, but you
don't want the borders on your header and footer controls
to print - in which case you would set PrintBorders
= Body. If you want borders on header,
body and footer set PrintBorders = All.
|
|
|
| Q: Print
different controls from a single Form (e.g. Tab pages)
on each page of the printout? |
| A:
This process is illustrated in the MultiPage sample.
(See the associated readme file).
In summary, the following occurs in this sample:
The PrintForm QueryPageSettings event
is handled, and is used to change the BodyContainer
property of PrintForm for each successive page. In the
PrintForm.PrintPage event handler the
process is terminated when we have printed all the controls
we need to print (in this case tab pages of a tab control). |
|
|
| Q: Print
different Forms on each page of the printout? |
| A:
This process is illustrated in the TaxForm sample. (See
the associated readme file).
In summary, the following occurs in this sample:
A different Form is added to the project for each page
of the printout. Each form has a PrintForm added, with
its BodyContainer set to the entire
Form. A main Form is added to the project, containing
a PrintChainManager component. A reference
to each of the PrintForm controls is added to the PrintChainManager.Documents
collection. When PrintChainManager prints, it chains
the sequence of pages printed by each of the PrintForm
controls into a single document.
Note: any object that implements the
IChainedDocument interface can participate
in the print job managed by the PrintChainManager. See
the IChainedDocument documentation for details of how
to implement this interface on your own classes. Products
from TMG Development Ltd that support this interface
include PrintForm and the PrintAdapters suite (PrintListView,
PrintTreeView, PrintDataTable, PrintRichTextBox).
|
|
|
| Q: Print
a Form which is larger than the paper size over multiple
pages? |
| A:
This process is illustrated in the PrintLargeControl
sample. (See the associated readme file).
In summary, the following occurs in this sample:
The PrintForm.PrintControl method
is used to render a portion of the Form into the MarginBounds
rectangle on each successive page. The Form is divided
into a number of 'Tiles' each with an offset from the
origin (top left) of the control. To print each Tile
we repeatedly print the Form, negatively offset by the
specified amount, while the Graphics.Clip
region is set to the page MarginBounds rectangle to
exclude any portion of the Control not in the current
Tile.
|
|
|
| Q: Print
a control inside a UserControl with a different BackColor? |
|
| Q: Set
UseLegacyPrinting, BackColorWhilePrinting, VisibleWhilePrinting
settings on controls that are inside a UserControl? |
| A:
The problem with controls contained within a UserControl
is that the Visual Studio designer doesn't see them,
and consequently you can't set any of the PrintForm
extender properties for them whilst in the designer.
The solution is to set them at runtime via the appropriate
Set<extender-property-name> function.
This process is illustrated in the UserControlWithLegacy
sample. (See the associated readme file).
|
|
|
| Q: Print
more than one Form / container control (tab, panel etc)
on the same page? |
| A:
The default behavior of PrintForm is to print a single
nominated control (referenced by the BodyContainer
property) into the MarginBounds rectangle
of the page. This architecture is designed for simplicity
(see Print a Form with One Line
Of Code), but in more complex scenarios you may
have a tab control on a Form where you want to print
all the tabs on one page. In this situation you would
use the PrintForm.PrintControl() method
which allows you to render any control you like at any
position on the page.
This process is illustrated in the PrintMultipleHiddenForm
sample. (See the associated readme file).
|
|
|
| Q: Print
the Page image to a file? |
| A:
The PrintToFile sample (See the associated readme file)
shows how to print a representation of the printed page
(headers and footers included) to a file. It uses a
specialization of the .NET class PrintController,
called FilePrintController, which is
included in this project (.NET provides a StandardPrintController,
PrintControllerWithStatusDialog and PreviewPrintController).
FilePrintController supplies a Graphics object obtained
from a Bitmap to the standard printing mechanism. You
could use this class to print to any of the file formats
.NET supports even if you were not using PrintForm to
render your printed output.
If you just want to save an image of a given control
or Form to a file you can use code similar to the following:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
' Save an image of the Form
Dim target As Control = Me
Dim r As Rectangle = New Rectangle(New Point(0, 0), target.Size)
Dim img As New Bitmap(r.Width, r.Height)
Dim g As Graphics = Graphics.FromImage(img)
Me.PrintForm1.PrintControl(g, r, target, 1.0)
g.Dispose()
img.Save("c:\image.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
img.Dispose()
End Sub
See the PrintToBitmap sample for further details (See
the associated readme file).
|
|
|
| Q: Print
multiple Page images to a TIFF file? |
| A:
The PrintToMultiPageTiffFile sample (See the associated
readme file) shows how to print multiple pages into
a single multi-page .tif (TIFF) file. It uses a specialization
of the .NET class PrintController, called FilePrintController,
which is included in this project. FilePrintController
supplies a Graphics object obtained from a Bitmap to
the standard printing mechanism and appends each Bitmap
to a single TIFF image. |
|
|
| Q: Print
a Form or control scaled to custom size? |
| A:
Perform the following steps:
- Drag a PrintForm component onto your Form
- Set the PrintForm.BodyContainer
property to reference your Form
- Set PrintForm.AutoFit = None,
to prevent PrintForm from automatically scaling up
the Form to fit the page.
- Set PrintForm.ManualZoom to the
scale you want, say 0.5
- Set PrintForm.CenterStyle to control
how the image is centered on the page.
- Add a button and button click handler. In the handler
call PrintForm.Print()
Alternatively if you are using the PrintForm.PrintControl()
method in a custom printing scenario you can set the
scale of the output in the 4th parameter.
|
|
|
| Q: Print
without showing the 'Printing Page n' dialog? |
| A:
The solution here is to change the PrintController
that the .NET printing mechanism uses. By default it
uses a PrintControllerWithStatusDialog
object, but there is also one in the .NET framework
which doesn't display the status dialog, called StandardPrintController.
Set the PrintController property of PrintForm as follows,
before calling Print, or doing a PrintPreview:
Me.PrintForm1.PrintController = New System.Drawing.Printing.StandardPrintController() |
|
|
| Q: Print
a hidden Form / control? |
| A:
You will not always want to show the form you are about
to print to the user, for example in a batch printing
application, or where the layout of the printed form
is required to be different to the user interface. In
this situation you might expect to be able to simply
call PrintForm.Print() without displaying
the Form, once you had setup the required PrintForm
properties. In fact some controls (TextBox, ListBox,
Combo etc) will not appear on the printed output if
you do this because they rely on Win32 controls internally
which are detecting that they are not visible and are
optimizing the repainting of the form by not displaying
themselves.
The solution to this legacy control problem is to make
sure that the form is visible, but just out of view.
To this end the technique we use in this sample is to
re-parent the form we wish to print to our main application's
form, move it out of view and then print it.
This process is illustrated in the PrintHiddenForm
sample. (See the associated readme file).
|
|
|
| Q: Handle
rendering of a legacy control myself? |
| A:
A very few legacy controls may not respond to the methods
that PrintForm uses to get them to render themselves
into the printout. In this situation it may be that
the control offers some other mechanism for obtaining
an image of it's contents (Save to file, copy to clipboard
etc). If this is the case PrintForm provides an event,
the PreDraw event, that you can handle
to take charge of rendering the control yourself.
Here is some sample code that shows how to use a legacy
control's SaveBitmapImage function to copy an image
of its client area onto the clipboard, and then render
that image into the printout. In this case the legacy
control is a Nevron 3D Chart ActiveX control:
Private Sub PrintForm1_PreDraw(ByVal e As TMGDevelopment.PrintForm.PreDrawEventArgs) _
Handles PrintForm1.PreDraw
' look for the control we're interested in
If e.Control Is Me.NChart1 Then
' this code is from the following Nevron sample and is specific to the Nevron ActiveX control:
' Nevron\3DChart\Example Files\Examples\3DChart\Visual Basic 6\ImportExport\Clipboard
Dim vFile As Object
Dim bUseWindowDim, bOK As Boolean
Dim nHeight, nWidth, nBitsPerPixel As Integer
bUseWindowDim = True
nBitsPerPixel = 24
nHeight = e.Bounds.Height
nWidth = e.Bounds.Width
' a variant with an empty string indicates that we want to use the clipboard
vFile = ""
NChart1.ImportExport.SaveBitmapImage(vFile, bUseWindowDim, nWidth, nHeight, nBitsPerPixel)
' this is generic code for getting a bitmap from the clipboard and drawing it:
Dim iData As IDataObject = Clipboard.GetDataObject()
Dim img As System.Drawing.Bitmap = iData.GetData(DataFormats.Bitmap, True)
e.Graphics.DrawImage(img, e.Bounds)
e.OwnerDrawn = True ' tell PrintForm we've drawn this control
End If
End Sub
|
|
|
|
|
|