Solved

printing datagrid in vb.net

Posted on 2004-09-30
18
480 Views
Last Modified: 2010-04-23
i have a datagrid on my form, its datasource is from a datatable that i have created. how can i print off all the values of my datagrid??any websites that have this ?

ps: i dont want to use crystal reports and i dont want to know how to do it in c#
0
Comment
Question by:evo14sale
  • 8
  • 3
  • 2
  • +2
18 Comments
 

Author Comment

by:evo14sale
ID: 12197464
with print preview functionality
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12198234
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12198245
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12198253
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12198303
0
 
LVL 27

Expert Comment

by:planocz
ID: 12198847
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12198905
Interesting link Planocz, (It refers to this question)
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 27

Expert Comment

by:planocz
ID: 12198942
0
 
LVL 28

Accepted Solution

by:
iboutchkine earned 150 total points
ID: 12198949
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
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12199315
Hi again planocz,

That link was already submitted. ;-)
0
 
LVL 27

Expert Comment

by:planocz
ID: 12199548
Right Ron, I missed that one sorry to step on toes.
0
 
LVL 25

Expert Comment

by:RonaldBiemans
ID: 12199721
No problem planocz, there were no toes that were stepped on :-)
0
 

Author Comment

by:evo14sale
ID: 12224486
Hi have the following code, it was taking from the msdn site and will print but how can i get the print preview for this?do i have to programmatically have to do this or is there a simplier way?any code wud b much appreciated

Private Sub PrintGrid_Click(ByVal sender As System.Object, ByVal e As _
   System.EventArgs) Handles PrintGrid.Click
   PrintDocument1.Print()
End Sub

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
   ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles _
   PrintDocument1.PrintPage
   Dim myPaintArgs As New PaintEventArgs(e.Graphics, New Rectangle(New _
      Point(0, 0), Me.Size))
   Me.InvokePaint(DataGrid1, myPaintArgs)
End Sub
0
 
LVL 25

Assisted Solution

by:RonaldBiemans
RonaldBiemans earned 150 total points
ID: 12229622
0
 

Expert Comment

by:zolox1
ID: 14149179
I have use the code but there is problem ...that's some rows that over char(20) dosn't show after that print
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

757 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

18 Experts available now in Live!

Get 1:1 Help Now