65.9K
CodeProject 正在变化。 阅读更多。
Home

PrintForm 组件 1.0 详解

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.92/5 (9投票s)

2007 年 6 月 30 日

8分钟阅读

viewsIcon

154203

downloadIcon

1

如何使用 PrintForm 组件在 VB.NET 中打印窗体。描述了各种方法以及示例,说明如何根据需要自定义打印输出。

引言

“PrintForm 组件旨在恢复轻松打印 Windows 窗体的功能。”

本文从使用 PrintForm 组件和简单窗体打印的基本步骤开始,描述了使用代码示例(必要时)自定义打印的各种选项,并解决了使用中遇到的一些问题。

背景

大约在以前,我正在用 VB.NET 开发一个需要打印报表的项目。那是一项非常耗时的工作,因为当时没有可用的类似组件。与 VB 相比,这是使用 VB.NET 的一个大缺点。但现在,PrintForm 组件的发布对于 VB.NET 开发人员以及那些试图将项目从 VB 升级到 VB.NET 的人来说,都是一大福音,因为你不再需要生成冗长的 GDI 调用序列。你可以简单地按照需要,用最少的代码打印你的窗体。然而,尽管 PrintForm 组件使用起来简单方便,但关于它的问题和疑问已在几乎所有开发人员网站的论坛上发布,而且几乎没有给出任何示例。这使我决定撰写关于此组件的文章。

如何开始

首先。如果你还没有下载和安装 PrintForm 组件,你需要先下载并安装它。这是下载链接:http://msdn2.microsoft.com/en-us/vbasic/aa701261.aspx
安装非常简单,通常不会出现问题。安装后,你需要将其添加到工具箱中,然后才能将其拖放到窗体上

  1. 在 Visual Studio .NET 编辑器中,右键单击工具箱的“常规”选项卡,然后选择“自定义工具箱...”
    或将其添加到 Windows 窗体选项卡中
    或创建一个新选项卡。
  2. 选择“自定义工具箱”对话框的“.NET Framework 组件”选项卡,然后向下滚动直到找到“PrintForm”。
  3. 选中它并单击“确定”。

    现在,你可以将 PrintForm 组件从工具箱的“常规”选项卡拖到窗体的组件托盘上。PrintForm 为窗体上的每个控件以及窗体本身扩展了新属性,可以根据要求进行设置。

打印窗体

要打印整个窗体,请执行以下步骤

  1. 从 Visual Studio 工具箱中将 PrintForm 组件拖到窗体上
  2. PrintForm.BodyContainer 属性设置为引用你的窗体
  3. 添加一个按钮和按钮单击处理程序。在处理程序中调用 PrintForm.Print()

预览窗体打印

通常,在实际打印之前,你需要预览窗体,尤其是在测试期间,以便你可以相应地调整属性,当然不要忘记,还可以节省纸张(从而节省树木)
可以按如下方式完成

  1. 从 Visual Studio 工具箱中将 PrintForm 组件拖到窗体上
  2. PrintForm.BodyContainer 属性设置为引用你的窗体
  3. 从 Visual Studio 工具箱中将 PrintPreviewDialog 组件拖到窗体上
  4. PrintPreviewDialog.Document 属性设置为引用 PrintForm 组件
  5. 添加一个按钮和按钮单击处理程序。在处理程序中调用 PrintPreviewDialog.ShowDialog()
    Private Sub Button1_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles Button1.Click
            ' If you don't want the print button to print the print button
            Button1.Visible = False
            ' Set the PrintAction to display a Print Preview dialog
            PrintForm1.PrintAction = Printing.PrintAction.PrintToPreview
            ' This prints a copy of the form as it appears in the PrintPreview
            PrintForm1.Print()
            ' Display the print button again on the form
            Button1.Visible = True
        End Sub 

自定义窗体打印输出

为了更改打印输出上窗体的背景颜色,你可以设置窗体的 BackColorWhilePrinting 属性。窗体上所有控件的背景颜色都将更改。但是,如果你想为不同的窗体指定不同的颜色,则可以为各个控件设置此属性。

如果你不希望窗体上的特定控件被打印(例如,命令按钮),你可以为窗体上的这些控件设置 VisibleWhilePrinting 属性。

为了在水平或垂直方向,或两者都将打印的窗体居中,你可以使用 PrintForm.CenterStyle 属性。

当你要打印的窗体或控件小于打印页的边距时,PrintForm 使用 CentreStyle 设置来使输出居中,或者将输出打印在边距矩形的左上角,请设置 CenterStyle = CenterStyle.None

要将窗体缩放以填充打印页,将 AutoFit 属性设置为以下值之一可控制此行为:PageElement.NonePageElement.BodyPageElement.All

要向打印输出添加页眉和页脚,有三个属性可以设置为指向单个控件:HeaderContainerBodyContainer FooterContainer。在 BodyContainer 属性中引用的控件内容将在页面的边距矩形内呈现,HeaderContainer FooterContainer (如果指定)将分别在边距矩形的正上方和正下方呈现。

因此,你必须在窗体中添加两个额外的面板,在这些面板中,你将添加将作为页眉和页脚出现的控件。然后,将 HeaderContainer 设置为页眉面板,将 BodyContainer 设置为窗体,将 FooterContainer 设置为页脚面板,确保通过适当设置其位置(例如,设置为 (-1000, -1000))或仅在打印时使其可见,使它们在窗体表面不可见。

边距宽度由 PageSettings 对象的 Margins 属性控制。要设置边距宽度

  1. 设置 PrintDocument.DefaultPageSettings.Margins 属性以控制 PrintDocument 打印的所有页面的默认边距大小
    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  
  2. 或在 PrintDocument.QueryPageSettings 事件中设置 e.PageSettings.Margins 以单独设置每个打印页的边距大小
    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 

你可以使用 PrintForm.PrintBorders 属性打开或关闭正在渲染的最外层控件的边框。

你可能需要在打印输出的每一页上打印来自单个窗体的不同控件。你可以通过为每一页更改 PrintForm BodyContainer 属性来做到这一点。

你还可以通过向每个窗体添加一个 PrintForm 组件,并将其 BodyContainer 设置为整个窗体,来在打印输出的每一页上打印不同的窗体。向项目中添加一个主窗体,其中包含一个 PrintChainManager 组件,并向 PrintChainManager.Documents 集合添加对每个 PrintForm 控件的引用。

你可以使用 PrintForm.PrintControl() 方法在同一页上打印多个窗体或容器控件,该方法允许你在页面上的任何位置渲染你喜欢的任何控件。

要将大于纸张尺寸的窗体打印到多页,PrintForm.PrintControl 方法用于将窗体的一部分渲染到每个连续页上的 MarginBounds 矩形中。窗体被分成若干“Tiles”,每个 Tile 都与控件的原点(左上角)有一个偏移量。要打印每个 Tile,请重复打印窗体,负向偏移指定的量,同时将 Graphics.Clip 区域设置为页面 MarginBounds 矩形,以排除不在当前 Tile 中的控件的任何部分。

要在 UserControl 内部使用不同的 BackColor 打印控件,请在 UserControl 内部的控件上设置 UseLegacyPrintingBackColorWhilePrintingVisibleWhilePrinting 设置。

通常需要将窗体或控件缩放至自定义大小进行打印。可以按如下方式完成

  1. PrintForm 组件拖到窗体上
  2. PrintForm.BodyContainer 属性设置为引用你的窗体
  3. 设置 PrintForm.AutoFit = None,以防止 PrintForm 自动缩放窗体以适应页面。
  4. PrintForm.ManualZoom 设置为你想要的比例,例如 0.5
  5. 设置 PrintForm.CenterStyle 以控制图像如何在页面上居中。
  6. 添加一个按钮和按钮单击处理程序。在处理程序中调用 PrintForm.Print()
    或使用 PrintForm.PrintControl() 方法并在第四个参数中设置输出比例。

有时,你可能希望打印隐藏的窗体/控件,例如,当打印窗体的布局需要与用户界面不同时。为此,你只需在设置好所需的 PrintForm 属性后,调用 PrintForm.Print() 而不显示窗体。基本上,窗体是可见的,但只是不在视野中。

打印到文件

要将页面图像打印到文件,请使用 .NET 类 PrintController 的专用类,称为 FilePrintControllerFilePrintController 将从 Bitmap 获取的 Graphics 对象提供给标准打印机制。即使你不使用 PrintForm 来渲染打印输出,此类的也可以用于打印到 .NET 支持的任何文件格式。

你可以使用以下代码来实现此目的

' 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() 

同样,你可以使用上述类将多个页面图像打印到 TIFF 文件。

要不显示“正在打印页面”对话框进行打印,请使用 StandardPrintController。在调用 Print 或执行 PrintPreview 之前,按如下方式设置 PrintForm PrintController 属性

Me.PrintForm1.PrintController = New
            System.Drawing.Printing.StandardPrintController()

一些问题

你可能会发现窗体上的一些控件在打印时没有显示。这是因为 .NET 中的一些控件和一些第三方控件没有完全托管或没有按照 .NET 控件指南编写。因此,它们被标记为“传统”控件。选择该控件并将其 UseLegacyPrinting 属性设置为 true。这应该可以解决问题。极少数传统控件可能不会响应 PrintForm 用于使其自身渲染到打印输出中的方法。

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 clipboard
    vFile = ""
    NChart1.ImportExport.SaveBitmapImage(vFile, bUseWindowDim, nWidth,
                        nHeight, nBitsPerPixel)

    ' this is generic code for getting a bitmap from 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 

该控件可能提供一些其他机制来获取其内容的图像。如果是这种情况,PrintForm 提供了一个事件,即 PreDraw 事件,你可以处理该事件以自行负责渲染控件。这已在上面的代码片段中显示。

你可能还需要将 PrintForm 和打印链程序集与你的应用程序一起分发。有几种方法可以找到正确的程序集

  • 为你的应用程序构建一个安装程序项目,它将自动拉入正确的版本。
  • 或者将项目中 printform 和 printchaining 引用的本地复制设置为 true,这将导致 VS.NET 将它们复制到你的 bin 目录,你可以从那里与你的 EXE 一起获取它们,并将它们复制到目标机器上你的 EXE 的相同位置。
  • 或者从它们的安装位置手动复制它们

结论

在 VB.NET 中使用 PrintForm 组件打印 Windows 窗体是实现 VB.NET 中 VB 类型单行 printform() 方法的一种非常简单有效的方法。我希望我的尝试对从事这方面工作的人有所帮助。我将尝试用更多的示例和样本来更新文章。

© . All rights reserved.