Solved

Print out DataGrid Records

Posted on 2004-10-25
172 Views
Last Modified: 2010-04-23
Hi,

I need to print out a records from my DataGrid,

The out put is something like this;
 
Cin# XC9050426249L1JL   Batch# 6249  Chassis# 0123456ABCDEF123456   -> 1st row
 
Notes: I need print out each row record.

I wish to have Preview button to preview the data before print out, and a Print button to print out the record as show above.

Can Help?
0
Question by:kaifong78
    4 Comments
     
    LVL 25

    Accepted Solution

    by:
    0
     
    LVL 27

    Expert Comment

    by:planocz
    Hi Ron, I like your link :)
    0
     
    LVL 25

    Expert Comment

    by:RonaldBiemans
    Hi planocz,

    Yeah, the guy that provided the answer really knows his stuff ;-)
    0
     
    LVL 28

    Assisted Solution

    by:iboutchkine
    Prints multiple pages

    Form1 - startup
    Imports System.Data.OleDb

    Public Class Form1
        Inherits System.Windows.Forms.Form

    #Region " Windows Form Designer generated code "

        Public Sub New()
            MyBase.New()

            'This call is required by the Windows Form Designer.
            InitializeComponent()

            'Add any initialization after the InitializeComponent() call

        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents dg As System.Windows.Forms.DataGrid
        Friend WithEvents btnPrint As System.Windows.Forms.Button
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.dg = New System.Windows.Forms.DataGrid
            Me.btnPrint = New System.Windows.Forms.Button
            CType(Me.dg, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.SuspendLayout()
            '
            'dg
            '
            Me.dg.DataMember = ""
            Me.dg.HeaderForeColor = System.Drawing.SystemColors.ControlText
            Me.dg.Location = New System.Drawing.Point(0, 0)
            Me.dg.Name = "dg"
            Me.dg.Size = New System.Drawing.Size(292, 196)
            Me.dg.TabIndex = 0
            '
            'btnPrint
            '
            Me.btnPrint.Location = New System.Drawing.Point(8, 220)
            Me.btnPrint.Name = "btnPrint"
            Me.btnPrint.TabIndex = 1
            Me.btnPrint.Text = "Print"
            '
            'Form1
            '
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(292, 266)
            Me.Controls.Add(Me.btnPrint)
            Me.Controls.Add(Me.dg)
            Me.Name = "Form1"
            Me.Text = "Form1"
            CType(Me.dg, System.ComponentModel.ISupportInitialize).EndInit()
            Me.ResumeLayout(False)

        End Sub

    #End Region
        Private dge As New DataGridEx

        Dim cn As OleDbConnection
        Dim sConn As String = _
         "Provider=Microsoft.Jet.OLEDB.4.0;" & _
         "Data Source=C:\TestDB\TestDB.mdb;"

        Dim ds As DataSet
        Dim da As OleDbDataAdapter
        Dim sSQL As String = "SELECT * FROM Test"
        Dim sSource As String = "Test"

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.CreateDS()
            dg.DataSource = ds
            dg.DataMember = "Test"
        End Sub
        Private Sub CreateDS()
            ds = New DataSet
            'Connect to database and specify sSQL
            da = New OleDbDataAdapter(sSQL, sConn)

            Try
                'using DataAdapter enter records from table to DataSet
                da.Fill(ds, sSource) 'fsSource is a table
            Catch objExc As System.Exception
                'if error happend then email or write to Log?
                Exit Sub
            End Try

        End Sub
     

        Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
            Dim obj, obj2 As Object

            obj2 = New DataView(ds.Tables("Test"))
            dge.Print(obj2, ds.Tables("Test"), CType(Me.BindingContext(dg.DataSource), CurrencyManager))
            MsgBox("Done")
        End Sub
    End Class
    ================================================================
    Class DataGridEx

    Public Class DataGridEx
        Inherits DataGrid

        Protected protCustomColumnsHeaders As Boolean
        Protected protOldHeaderFont As Font
        Protected protNRowsInCaption As Integer
        Protected protRowHeaderWidth As Integer

        Private components As System.ComponentModel.IContainer

        Public Function CreateTableStyle(ByVal Table As DataTable) As DataGridTableStyle
            Dim ts1 As New DataGridTableStyle
            ts1.MappingName = Table.TableName
            Dim i As Integer
            For i = 0 To Table.Columns.Count - 1
                If Table.Columns(i).DataType Is GetType(Boolean) Then
                    Dim boolCol As New DataGridBoolColumn '       DataGridBoolColumnEx
                    boolCol.MappingName = Table.Columns(i).ColumnName
                    boolCol.HeaderText = Table.Columns(i).ColumnName
                    ts1.GridColumnStyles.Add(boolCol)
                Else
                    Dim TextCol As New DataGridTextBoxColumn '   DataGridTextBoxColumnEx
                    TextCol.MappingName = Table.Columns(i).ColumnName
                    TextCol.HeaderText = Table.Columns(i).ColumnName
                    ts1.GridColumnStyles.Add(TextCol)
                End If
            Next
            Me.TableStyles.Add(ts1)
            Return ts1
        End Function

        Private storedPageSettings As System.Drawing.Printing.PageSettings
        Public Property PageSettings() As System.Drawing.Printing.PageSettings
            Get
                Return storedPageSettings
            End Get
            Set(ByVal Value As System.Drawing.Printing.PageSettings)
                storedPageSettings = Value
            End Set
        End Property

        Public Sub PageSetup()
            Try
                Dim psDlg As New PageSetupDialog

                If (storedPageSettings Is Nothing) Then
                    storedPageSettings = New System.Drawing.Printing.PageSettings
                End If

                psDlg.PageSettings = storedPageSettings
                psDlg.ShowDialog()
            Catch ex As Exception
                'msgbox('error")
            End Try

        End Sub

        Public Sub Print(ByVal objView As DataView, ByVal objTable As DataTable, ByVal cm As CurrencyManager)
            Try
                'Assumes the default printer
                Dim pd As DataGridPrintDocument = New DataGridPrintDocument(Me, objView, objTable, cm, -1, Nothing)

                If Not (storedPageSettings Is Nothing) Then
                    pd.DefaultPageSettings = storedPageSettings
                End If


                Dim dlg As New PrintDialog
                dlg.Document = pd
                Dim result As DialogResult = dlg.ShowDialog()

                If (result = DialogResult.OK) Then
                    pd.Print()
                End If

            Catch ex As Exception
                'InformationMessageModule.InformationMessage("An error occurred printing the DataGrid - " & ex.Message)
            End Try

        End Sub

        Public Property CustomColumnHeaders() As Boolean
            Get
                Return protCustomColumnsHeaders
            End Get
            Set(ByVal Value As Boolean)
                If Value Then
                    If protCustomColumnsHeaders = False Then
                        protOldHeaderFont = Me.HeaderFont
                        Dim g As Graphics = Me.CreateGraphics()
                        Me.HeaderFont = New Font(System.Drawing.FontFamily.GenericSerif, (protNRowsInCaption) * Me.HeaderFont.GetHeight(g) - 8, FontStyle.Regular, GraphicsUnit.Point)
                        g.Dispose()
                        protRowHeaderWidth = Me.RowHeaderWidth
                    End If
                    Me.CaptionVisible = False
                    Me.ColumnHeadersVisible = True
                Else
                    If Not Me.HeaderFont Is Nothing Then Me.HeaderFont.Dispose()
                    Me.HeaderFont = Me.protOldHeaderFont
                    Me.protOldHeaderFont = Nothing
                    Me.CaptionVisible = True
                    Me.ColumnHeadersVisible = True
                End If
                protCustomColumnsHeaders = Value
            End Set
        End Property

        Public ReadOnly Property CustomColumnHeaderHeight() As Integer
            Get
                Return Me.HeaderFont.Height
            End Get
        End Property

        Public ReadOnly Property CustomColumnHeaderFont() As Font
            Get
                If protCustomColumnsHeaders Then
                    Return Me.protOldHeaderFont
                End If
                Return Me.HeaderFont
            End Get
        End Property

        Public Sub PaintHeaderCell(ByVal g As Graphics, ByVal Sentence As String, ByVal F As Font, ByVal br As Brush, ByVal Bounds As Rectangle, ByVal offsetx As Integer, ByVal offsety As Integer)
            Dim strs(protNRowsInCaption - 1), tt() As String
            tt = Sentence.Split(" "c)
            Dim i, j, n As Integer
            j = 0
            Dim s As String = ""
            Dim os As String
            os = s
            For i = 0 To protNRowsInCaption - 1
                strs(i) = ""
            Next
            For i = 0 To tt.Length - 1
                If s <> "" Then
                    s &= " " & tt(i)
                Else
                    s = tt(i)
                    os = s
                End If
                Dim w As Integer = CInt(g.MeasureString(s, F).Width)
                If w >= Bounds.Width Then
                    strs(j) = os
                    If s <> tt(i) Then
                        s = tt(i)
                        os = tt(i)
                    Else
                        s = ""
                        os = ""
                    End If
                    If j = protNRowsInCaption - 1 And i <= tt.Length - 1 Then
                        strs(j) = "..."
                        Exit For
                    End If
                    j += 1
                Else
                    os = s
                End If
                If i = tt.Length - 1 And j <> protNRowsInCaption Then
                    strs(j) = s
                End If
            Next
            n = Me.protNRowsInCaption - 1
            Dim h As Integer = (Bounds.Height Mod F.Height) \ 2
            For i = 0 To n
                Dim w As Integer = CInt(g.MeasureString(strs(i), F).Width)
                If w < Bounds.Width Then
                    w = (Bounds.Width - w) \ 2
                Else
                    If Bounds.Width > 0 Then
                        While w >= Bounds.Width
                            strs(i) = strs(i).Substring(0, strs(i).Length - 1)
                            w = CInt(g.MeasureString(strs(i), F).Width)
                        End While
                    Else
                        Return
                    End If
                    w = 0
                End If
                g.DrawString(strs(i), F, br, Bounds.X + w + offsetx, Bounds.Y + h + offsety)
                h += F.Height
            Next
        End Sub

        Public Function GetHeaderWidth(ByVal g As Graphics, ByVal Text As String) As Integer
            Dim strs() As String
            strs = Text.Split(" "c)
            Dim ws(strs.Length - 1) As Integer
            Dim i, n As Integer
            n = Math.Min(ws.Length - 1, Me.protNRowsInCaption - 1)
            Dim f As Font
            If protCustomColumnsHeaders Then
                f = protOldHeaderFont
            Else
                f = Me.HeaderFont
            End If
            For i = 0 To n
                ws(i) = CInt(g.MeasureString(strs(i), f).Width)
                GetHeaderWidth = Math.Max(GetHeaderWidth, ws(i))
            Next
        End Function
    End Class

    ================================================================
    Class DataGridPrintDocument

    Imports System.Drawing.Printing

    Public Class DataGridPrintDocument
        Inherits PrintDocument

        Private printFont As Font
        Private headerFont As Font
        Private dataGridToPrint As DataGridEx
        Private objTable As DataTable
        Private objView As DataView
        Private privCM As CurrencyManager
        Private privNP As Integer
        Private privStrQuestion As String

        Public Sub New(ByVal dataGridToPrint As DataGridEx, ByVal objView As DataView, ByVal objTable As DataTable, ByVal privCM As CurrencyManager, _
        ByVal NP As Integer, ByVal Question As String)
            MyBase.New()
            Me.dataGridToPrint = dataGridToPrint
            If objView Is Nothing Then
                Me.objView = objTable.DefaultView
            Else
                Me.objView = objView
            End If
            Me.objTable = objTable
            Me.privCM = privCM
            privNP = NP
            privStrQuestion = Question
        End Sub

        Private npp As Integer
        'Override OnBeginPrint to set up the font we are going to use
        Protected Overrides Sub OnBeginPrint(ByVal ev As PrintEventArgs)
            MyBase.OnBeginPrint(ev)
            CurRow = 0
            CurCol = 0
            NextFirstCol = 0
            npp = 0
            headerFont = dataGridToPrint.HeaderFont
            printFont = dataGridToPrint.DefaultFont
        End Sub

        Dim CurRow, CurCol As Integer
        Dim NextFirstCol As Integer
        'Override the OnPrintPage to provide the printing logic for the document
        Protected Overrides Sub OnPrintPage(ByVal ev As PrintPageEventArgs)

            MyBase.OnPrintPage(ev)

            NextFirstCol = 0
            npp += 1

            Dim lpp As Single = 0
            Dim yPos As Single = 0
            Dim count As Integer = 0
            Dim leftMargin As Single = ev.MarginBounds.Left
            Dim topMargin As Single = ev.MarginBounds.Top
            Dim line As String

            'Work out the number of lines per page
            'Use the MarginBounds on the event to do this
            lpp = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics)

            'Now iterate over the file printing out each line
            'NOTE WELL: This assumes that a single line is not wider than the page width
            'Check count first so that we don't read line that we won't print
            Dim tblStyle As DataGridTableStyle = dataGridToPrint.TableStyles(objTable.TableName)
            If tblStyle Is Nothing Then
                tblStyle = dataGridToPrint.CreateTableStyle(objTable)
            End If
            Dim rh As Integer = tblStyle.PreferredRowHeight
            Dim headerHeight As Integer
            If dataGridToPrint.CustomColumnHeaders = False Then
                headerHeight = rh
            Else
                headerHeight = dataGridToPrint.CustomColumnHeaderHeight
            End If
            Dim nrperpage As Integer = (ev.MarginBounds.Height \ rh) - (headerHeight \ rh)
            Dim i, j, w, l As Integer
            l = CInt(topMargin)
            w = CInt(leftMargin)
            Dim divPen As New Pen(dataGridToPrint.GridLineColor)
            Dim hfpen As New Pen(dataGridToPrint.HeaderForeColor)
            Dim hbBrush As New SolidBrush(dataGridToPrint.HeaderBackColor)
            Dim hfBrush As New SolidBrush(dataGridToPrint.HeaderForeColor)
            For j = CurCol To tblStyle.GridColumnStyles.Count - 1
                If w + tblStyle.GridColumnStyles(j).Width >= ev.MarginBounds.Right And j <> CurCol Then
                    NextFirstCol = j
                    Exit For
                End If
                If tblStyle.GridColumnStyles(j).Width = 0 Then GoTo continuefor
                Dim r As New Rectangle(w, l, tblStyle.GridColumnStyles(j).Width, headerHeight)
                Dim rf As New Drawing.RectangleF(w, l, r.Width, r.Height)
                ev.Graphics.FillRectangle(hbBrush, r)
                'ev.Graphics.DrawRectangle(Pens.Black, r)

                If dataGridToPrint.CustomColumnHeaders = False Then
                    ev.Graphics.DrawString(tblStyle.GridColumnStyles(j).HeaderText, headerFont, hfBrush, rf)
                Else
                    dataGridToPrint.PaintHeaderCell(ev.Graphics, tblStyle.GridColumnStyles(j).HeaderText, _
                        dataGridToPrint.CustomColumnHeaderFont, hfBrush, r, 0, 0)
                End If
                w += tblStyle.GridColumnStyles(j).Width
    continuefor:
            Next
            l += headerHeight
            For i = CurRow To nrperpage + CurRow - 1
                If i >= objView.Count Then Exit For
                w = CInt(leftMargin)
                For j = CurCol To tblStyle.GridColumnStyles.Count - 1
                    If w + tblStyle.GridColumnStyles(j).Width >= ev.MarginBounds.Right And j <> CurCol Then Exit For
                    If tblStyle.GridColumnStyles(j).Width = 0 Then GoTo continuefor2
                    Dim r As New Rectangle(w, l, tblStyle.GridColumnStyles(j).Width, rh)
                    Dim rf As New Drawing.RectangleF(w, l, r.Width, r.Height)
                    ev.Graphics.DrawRectangle(divPen, r)
                    ev.Graphics.DrawString(objView.Item(i).Item(j).ToString(), printFont, Drawing.Brushes.Black, rf)
                    w += tblStyle.GridColumnStyles(j).Width
    continuefor2:
                Next
                l += rh
            Next

            l = CInt(topMargin)
            w = CInt(leftMargin)
            For j = CurCol To tblStyle.GridColumnStyles.Count - 1
                If w + tblStyle.GridColumnStyles(j).Width >= ev.MarginBounds.Right And j <> CurCol Then
                    Exit For
                End If
                If tblStyle.GridColumnStyles(j).Width = 0 Then GoTo continuefor3
                Dim r As New Rectangle(w, l, tblStyle.GridColumnStyles(j).Width, headerHeight)
                ev.Graphics.DrawRectangle(Pens.Black, r)

                w += tblStyle.GridColumnStyles(j).Width
    continuefor3:
            Next

            CurRow = i
            'If we have more lines then print another page
            If (CurRow < objView.Count) Then
                ev.HasMorePages = True
            Else
                If NextFirstCol = 0 Then
                    ev.HasMorePages = False
                Else
                    CurRow = 0
                    CurCol = NextFirstCol
                    ev.HasMorePages = True
                End If
            End If
            divPen.Dispose()
            hfpen.Dispose()
            hbBrush.Dispose()
            hfBrush.Dispose()
        End Sub
    End Class
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    The Complete Ruby on Rails Developer Course

    Ruby on Rails is one of the most popular web development frameworks, and a useful tool used by both startups and more established companies to build strong graphic user interfaces, and responsive websites and apps.

    This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
    I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    This video discusses moving either the default database or any database to a new volume.

    856 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now