Come stampare la tabella datagridview con la sua intestazione in vb.net?

Sto creando una funzione di anteprima di stampa in un sistema che sto sviluppando che visualizzerà un’anteprima del datagridview che voglio stampare. Ho usato i codici di ooopsoft come riferimento e funziona bene tranne che per un piccolo problema.

Problema:

inserisci la descrizione dell'immagine qui

Nel si vede che manca la riga dgv con numero seriale 1. Sembra che l’intestazione abbia sovrascritto la prima riga. Ho provato una miriade di modi per risolverlo, ma non riesco ancora a trovare la soluzione. Ho provato ad uscire dalla finestra di anteprima di stampa e ad aprirla di nuovo, ma questo è il risultato che ho ottenuto. Penso che mi manca una riga di codice, ma non riesco a capire cosa. Per favore aiuto.

Il codice originale è un buon inizio ma ha un paio di bug e inefficienze:

  • Usa il flag newpage per stampare l’intestazione o la prima riga quando c’è una nuova pagina. Ovviamente lo vuoi davvero fare entrambe le cose
  • La stampa delle intestazioni delle colonne viene eseguita una volta per pagina, quindi non è necessario che si trovi nel ciclo di stampa dei dati
  • Non consente colonne o colonne invisibili con un allineamento diverso da quello predefinito, Ci potrebbero essere altre impostazioni di questo tipo che si desidera rendere conto.
  • Perché in realtà non sta stampando il numero corretto di righe, una volta sistemato, scoprirai che ristampa l’ultima riga della pagina precedente come prima riga di una nuova pagina.
  • C’è una grondaia o margine interno in modo che il testo non si stampa troppo vicino alla griglia – questo usa solo un offset di 1 o 2
  • Inoltre usa inutilmente single e RectangleF
  • Inoltre, non è pronto per la visualizzazione o la stampa del documento. Sarà inoltre necessario ripristinare mRow e newpage nel clic del pulsante o nell’evento BeginPrint .

Ho aggiunto alcuni commenti oltre a colorare la riga di intestazione e dimostrare come implementare elementi come una regola di RowPrePaint .

 Private mRow As Integer = 0 Private newpage As Boolean = True Private Sub PrintDocument1_PrintPage(sender As System.Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage ' sets it to show '...' for long text Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit) fmt.LineAlignment = StringAlignment.Center fmt.Trimming = StringTrimming.EllipsisCharacter Dim y As Int32 = e.MarginBounds.Top Dim rc As Rectangle Dim x As Int32 Dim h As Int32 = 0 Dim row As DataGridViewRow ' print the header text for a new page ' use a grey bg just like the control If newpage Then row = dgvZZ.Rows(mRow) x = e.MarginBounds.Left For Each cell As DataGridViewCell In row.Cells ' since we are printing the control's view, ' skip invidible columns If cell.Visible Then rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height) e.Graphics.FillRectangle(Brushes.LightGray, rc) e.Graphics.DrawRectangle(Pens.Black, rc) ' reused in the data pront - should be a function Select Case dgvZZ.Columns(cell.ColumnIndex).DefaultCellStyle.Alignment Case DataGridViewContentAlignment.BottomRight, DataGridViewContentAlignment.MiddleRight fmt.Alignment = StringAlignment.Far rc.Offset(-1, 0) Case DataGridViewContentAlignment.BottomCenter, DataGridViewContentAlignment.MiddleCenter fmt.Alignment = StringAlignment.Center Case Else fmt.Alignment = StringAlignment.Near rc.Offset(2, 0) End Select e.Graphics.DrawString(dgvZZ.Columns(cell.ColumnIndex).HeaderText, dgvZZ.Font, Brushes.Black, rc, fmt) x += rc.Width h = Math.Max(h, rc.Height) End If Next y += h End If newpage = False ' now print the data for each row Dim thisNDX As Int32 For thisNDX = mRow To dgvZZ.RowCount - 1 ' no need to try to print the new row If dgvZZ.Rows(thisNDX).IsNewRow Then Exit For row = dgvZZ.Rows(thisNDX) x = e.MarginBounds.Left h = 0 ' reset X for data x = e.MarginBounds.Left ' print the data For Each cell As DataGridViewCell In row.Cells If cell.Visible Then rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height) ' SAMPLE CODE: How To ' up a RowPrePaint rule 'If Convert.ToDecimal(row.Cells(5).Value) < 9.99 Then ' Using br As New SolidBrush(Color.MistyRose) ' e.Graphics.FillRectangle(br, rc) ' End Using 'End If e.Graphics.DrawRectangle(Pens.Black, rc) Select Case dgvZZ.Columns(cell.ColumnIndex).DefaultCellStyle.Alignment Case DataGridViewContentAlignment.BottomRight, DataGridViewContentAlignment.MiddleRight fmt.Alignment = StringAlignment.Far rc.Offset(-1, 0) Case DataGridViewContentAlignment.BottomCenter, DataGridViewContentAlignment.MiddleCenter fmt.Alignment = StringAlignment.Center Case Else fmt.Alignment = StringAlignment.Near rc.Offset(2, 0) End Select e.Graphics.DrawString(cell.FormattedValue.ToString(), dgvZZ.Font, Brushes.Black, rc, fmt) x += rc.Width h = Math.Max(h, rc.Height) End If Next y += h ' next row to print mRow = thisNDX + 1 If y + h > e.MarginBounds.Bottom Then e.HasMorePages = True ' mRow -= 1 causes last row to rePrint on next page newpage = True Return End If Next End Sub 

inserisci la descrizione dell'immagine qui inserisci la descrizione dell'immagine qui

Si noti che c’è una colonna Id impostata su invisibile nel DGV, la colonna Color è centrata e Price giustificato a sinistra – queste sono tutte le impostazioni prelevate dal controllo. Si noti inoltre che il testo viene spostato appena dalle griglie.


L’ultimo punto mRow sopra, sarà anche necessario ripristinare mRow e newpage nel clic del pulsante o nell’evento BeginPrint . significa questo:

 Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) Handles PrintDocument1.BeginPrint mRow = 0 newpage = True PrintPreviewDialog1.PrintPreviewControl.StartPage = 0 PrintPreviewDialog1.PrintPreviewControl.Zoom = 1.0 End Sub 

Dopo aver visualizzato l’anteprima, la variabile mRow indicherà che tutte le righe sono state stampate. Se l’utente fa clic su Stampa o torna indietro per un’altra anteprima, non verrà stampato nulla. Questo codice ripristina anche la prima pagina da mostrare e lo Zoom iniziale.