HasMorePages

venerdì 07 maggio 2004 - 18.50

xonica Profilo | Newbie

c'è qualcuno che può spiegare come funziona e.hasemorepages???

so che serve per cambiare pagina ma in pratica cosa avviene quando viene eseguita questa istruzione

ci vuole sempre dopo un e.hasmorepages=true un e.hasmorepages=false?

Brainkiller Profilo | Guru

Esattamente.
Quando tu crei un PrintDocument poi aggiungi un PrintPageEventHandler che è la funzione che viene eseguita ogni qual volta viene stampata una pagina. Se tu alla fine di questa funziona metti e.HasMorePages=false la stampa termina lì, se lo metti a .true prosegue stampando le pagine successive:
Quindi se tu hai 100 elementi in un array e li stai stampando e ne vuoi 20 per pagina, stampi i primi 20, successivamente fai un controllo di questo tipo

if (totalerighe <= 100)
e.HasMorePages = true;
else
e.HasMorePages = false;

Naturalmente totalerighe è un intero che conteggia quante righe sono state stampante e si incrementa ogni volta che viene stampato un elemento dell'array.

ciao
david

xonica Profilo | Newbie

Vorrei far stampare le colonne dell'intestazione di una listview su più pagine e ho usato questo codice postato sotto. Il problema è che non mi crea più pagine ma sovrascrive sempre sulla stessa.
DOVE STA L'ERRORE ???


[il codice che ho postato lo potete provare creando un nuovo progetto Windows e incollandolo interamente]

Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Codice generato da Progettazione Windows Form "

Public Sub New()
MyBase.New()
InitializeComponent()
End Sub

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

Private components As System.ComponentModel.IContainer

Friend WithEvents ListView1 As System.Windows.Forms.ListView
Friend WithEvents Button1 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ListView1 = New System.Windows.Forms.ListView()
Me.Button1 = New System.Windows.Forms.Button()
Me.SuspendLayout()
'
'ListView1
'
Me.ListView1.Anchor = (((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right)
Me.ListView1.Location = New System.Drawing.Point(16, 16)
Me.ListView1.Name = "ListView1"
Me.ListView1.Size = New System.Drawing.Size(368, 288)
Me.ListView1.TabIndex = 0
Me.ListView1.View = System.Windows.Forms.View.Details
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(328, 312)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(56, 24)
Me.Button1.TabIndex = 1
Me.Button1.Text = "print"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(400, 342)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button1, Me.ListView1})
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Dim WithEvents pDoc As Printing.PrintDocument

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer, x As Integer, y As Integer
Dim item As ListViewItem
For i = 1 To 10
ListView1.Columns.Add("Colonna " & Str(i), 100, HorizontalAlignment.Left)
Next
For x = 1 To 200
item = ListView1.Items.Add("Item " & Str(x))
For y = 1 To 9
item.SubItems.Add("Subitem " & Str(y))
Next
Next
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim PrintDialog1 As New PrintDialog()
pDoc = New Printing.PrintDocument()
PrintDialog1.Document = pDoc
PrintDialog1.AllowSomePages = True
If PrintDialog1.ShowDialog() = DialogResult.OK Then
pDoc.Print()
End If
End Sub

Private Sub pDoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pDoc.PrintPage
Dim i As Integer = 0
Dim myfont As New Font("Verdana", 10, FontStyle.Regular, GraphicsUnit.Pixel)
Dim ColWidth As Integer = 0
Dim PrintRect As Rectangle = e.MarginBounds
Dim posX As Integer = PrintRect.Left

e.Graphics.DrawLine(New Pen(Color.Black), PrintRect.Left, PrintRect.Top, PrintRect.Right, PrintRect.Top)
e.Graphics.DrawLine(New Pen(Color.Black), PrintRect.Left, PrintRect.Top + myfont.Height, PrintRect.Right, Pr

Brainkiller Profilo | Guru

Invece di postare il tuo codice così nel messaggio come ti ho scritto via email puoi fare uno zip e allegarlo al messaggio ?
Se riesci è meglio così provo a fare un test e a vedere che cosa succede.
Forse la soluzione è più rapida di ciò che sembra.

ciao
david

ans66 Profilo | Junior Member

Non riesco proprio a comprendere come avere la stampa di più pagine con "HasMorePages=TRUE". Invece di dilungarmi in spiegazioni allego un file zip con il mio codice.
L'idea è la seguente:

- Intestazione (che si deve ripetere ad ogni pagina)
- corpo (che deve essere formato da 25 righe)
- un contatore che dovrebbe attivare "HasMorePages=TRUE"

Il problema è che non riesco ad aggiornare un loop FOR NEXT che deve stampare le righe di un DatagridView1 su un Form

Grazie davvero a chiunque mi voglia aiutare..

ANS66

amdbook Profilo | Junior Member

Qualche tempo fà ho postato questo esempio: http://www.redangel.it/click_file.asp?m=1834&l=13, forse ti può aiutare.

ans66 Profilo | Junior Member

mi hai gia` dato una grossa mano in passato in merito a questo comando e ho usato la tua routine adattata ad hoc per stampa di piu` pagine di un datagrid. Il problema e` ritornato fuori pero` quando in forndo alle righe di una datagrid che viene stampato avvio una seconda routine, per stampe di Note (con testo giustificato - Sub Testo_Giust2 che trovi in fondo ), e mi trovo con la necessita` di avviare da questa seconda routine un ulteriore salto pagina... Spero che sia chiaro e in ogni caso allego di seguito le routine nella speranza che tu abbia voglia di darmi ancora una mano...Grazie

(P.S.: Ho cercato di evidenziare con ====== le due routine e il punto in cui dovrei avviare il salto pagina extra nella routine Testo_Giust2)

================================================================================================================
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim dirDoc As String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)
e.Graphics.DrawImage(Image.FromFile(dirDoc & "\SF.bmp"), 550, 10, 190, 150)
e.Graphics.DrawString(Date.Today.ToShortDateString, New Font("Arial", 12, FontStyle.Bold), Brushes.LightBlue, 20, 20)
e.Graphics.DrawString("ORDINE " & DataGridView1.Item(0, 0).Value, New Font("Arial", 18, FontStyle.Bold), Brushes.Red, 250, 50)
DataGridView1.Columns(0).Name = "Nr. Ordine"
DataGridView1.Columns(1).Name = "Cod. Meccan."
DataGridView1.Columns(2).Name = "Descrizione"
DataGridView1.Columns(3).Name = "Prezzo lordo"
DataGridView1.Columns(4).Name = "Q.tà"
DataGridView1.Columns(5).Name = "Netto"
DataGridView1.Columns(6).Name = "Tot. Netto"



Try
Static RigheStampate As Integer
Static PagineStampate As Integer

Dim Table As DataTable = CType(DataGridView1.DataSource, DataTable)
Dim RigheTotali As Integer = DataGridView1.Rows.Count - 1
Dim ControllaPagine As Boolean = True

'Crea l'intestazione
Dim Rect As Rectangle
Dim ColCorrente As Integer = 0 'Indica la colonna corrente
Dim Top As Integer = e.MarginBounds.Top 'Top = Margine superiore
Dim Left As Integer = e.MarginBounds.Left 'Left = Margine sinistro
Dim Height As Integer = DataGridView1.RowTemplate.Height

'Quante righe posso stampare su un foglio?
Dim MaxRighe As Integer = e.MarginBounds.Height / Height
'In totale quante pagine
Dim MaxPagine As Integer = DataGridView1.Rows.Count - 1 / MaxRighe

Dim BrHeader As SolidBrush = New SolidBrush(DataGridView1.ColumnHeadersDefaultCellStyle.BackColor)
Dim HFont As Font = DataGridView1.ColumnHeadersDefaultCellStyle.Font

For Each col As DataGridViewColumn In DataGridView1.Columns
'Testo dell'Header
Dim ColText As String = col.Name
'Rettangolo dell'Header corrente
Rect = New Rectangle(Left, Top, col.Width, Height)
'Colora l'Header
e.Graphics.FillRectangle(BrHeader, Rect)
'Linee dell'Intestazione
e.Graphics.DrawRectangle(New Pen(Color.Gray, 1), Rect)
'Disegna il testo dell'Header
e.Graphics.DrawString(ColText, HFont, Brushes.Black, Left, _
Top + (e.Graphics.MeasureString(ColText, HFont).Height / 2))
'Calcola la prossima coordinata Left
Left += col.Width
Next

'Stampa la righe
Dim BrRow As SolidBrush = New SolidBrush(DataGridView1.DefaultCellStyle.BackColor)
Dim PnRow As Pen = New Pen(DataGridView1.GridColor)
Dim RigaCorrente As Integer = 0
Dim CelText As String = vbNullString

For RigaCorrente = RigheStampate To RigheStampate + MaxRighe
Left = e.MarginBounds.Left
Top += Height
For Each col As DataGridViewColumn In DataGridView1.Columns
'Testo della cella
If Len(DataGridView1.Rows(RigaCorrente).Cells(col.Name).Value()) <> 0 Then
CelText = DataGridView1.Rows(RigaCorrente).Cells(col.Name).Value.ToString
Else
CelText = vbNullString
End If


'Rettangolo dell'Intestazione corrente
Rect = New Rectangle(Left, Top, col.Width, Height)
'Colora lo sfondo della cella
e.Graphics.FillRectangle(BrRow, Rect)
'Disegna le linee del rettangolo della cella
e.Graphics.DrawRectangle(PnRow, Rect)
'Disegna il testo della cella
e.Graphics.DrawString(CelText, DataGridView1.Font, Brushes.Black, Left, _
Top + (e.Graphics.MeasureString(CelText, DataGridView1.Font).Height / 2))
'Calcola la prossima coordinata Left
Left += col.Width
Next
'Incrementa il contatore delle righe stampate
RigheStampate += 1

'Ci sono altre righe?
If RigheStampate >= DataGridView1.Rows.Count - 1 Then
e.Graphics.DrawString("Totale Ordine: " & TextBox4.Text, New Font("Arial", 12, FontStyle.Bold), Brushes.Blue, 520, _
Top + (e.Graphics.MeasureString("Totale Ordine: ", DataGridView1.Font).Height / 2) + 30)


' qui il problema ====================================='
Call Testo_Giust2(e, "Note: " & TextBox1.Text, Top, Font)
'===================================================



ControllaPagine = False
e.HasMorePages = False

'Azzera le variabili Static per un successivo utilizzo
RigheStampate = 0
PagineStampate = 0
Exit For
End If
Next RigaCorrente


'Devo controllare le pagine se non ho ancora terminato il numero di righe da
'Stampare
If ControllaPagine Then
'Incrementea il contatore delle pagine stampate
PagineStampate += 1

'Controlla se ci sono altre pagine da stampare...
If PagineStampate < MaxPagine Then
'Ci sono altre pagine
e.HasMorePages = True
Else
'Fine delle pagine
e.HasMorePages = False

'Azzera le variabili Static per un successivo utilizzo
RigheStampate = 0
PagineStampate = 0
End If
End If

PrintPreviewDialog1.Close()
'Distrugge gli oggetti
BrHeader.Dispose()
BrRow.Dispose()
PnRow.Dispose()

Catch Ex As Exception
If Err.Number = 91 Then
MessageBox.Show("Nessun record scelto nella griglia!", "Nessun record!", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
MessageBox.Show(Err.Description & Space(2) & Err.Number)
End If
End Try
End Sub
===============================================================================================================
Public Sub Testo_Giust2(ByVal pr As System.Drawing.Printing.PrintPageEventArgs, ByVal Testo As String, ByVal Alto As Single, ByVal Font As System.Drawing.Font)

Testo = Testo.Replace(Chr(10), "")
Testo = Testo.Replace(Chr(13), Space(1))
Testo = Testo.Replace(Space(2), Space(1))

Dim LargRiga As Single = (pr.MarginBounds.Right - pr.MarginBounds.Left)
Dim ritStr() As String = Split(Testo, Space(1))
Static RigaControllo As String = vbNullString
Static RigaDaScriv As String = vbNullString
Dim NrParola As Integer = 0, i As Integer = 0
Static LunghParola As Integer = 0

Alto = Alto + 90

For i = 0 To UBound(ritStr) - 1


If pr.Graphics.MeasureString(RigaControllo, Font).Width <= LargRiga Then
RigaControllo = RigaControllo & ritStr(i) & Space(1)
LunghParola = ritStr(i).Length + 1

Else

RigaDaScriv = Mid(RigaControllo, 1, RigaControllo.Length - LunghParola)
CentraTesto(pr, Alto, RigaDaScriv, Font, LargRiga)
' qui passi a funzione CentraTesto
Alto = Alto + 15
'==============================================================================

if Alto= 750 then
' qui devo inserire un nuovo salto pagina'
end if
'==============================================================================
RigaControllo = Mid(RigaControllo, RigaDaScriv.Length + 1)
LunghParola = RigaControllo.Length
i = i - 1
End If

If i = UBound(ritStr) - 1 AndAlso pr.Graphics.MeasureString(RigaControllo, Font).Width <= LargRiga Then
RigaControllo = RigaControllo & ritStr(i + 1)
pr.Graphics.DrawString(RigaControllo, Font, Brushes.Black, pr.MarginBounds.Left, Alto)
End If


Next

RigaControllo = vbNullString
RigaDaScriv = vbNullString


End Sub

ans66 Profilo | Junior Member

ho capito come fare: ho dovuto calcolare in anticipo il numero di righe il numero di righe (salvando in una matrice di stringhe) prima di far partire la funzione per testo giustificato. Nel ciclo for to maxrighe calcolo anche le righe dopo il datagrid. Ho dovuto prima capire concettualmente come funziona e.hasmorepages. Tutto risolto grazie.

sergio58 Profilo | Junior Member

Scusa, siccome la questione del calcolo del numero delle pagine in anticipo , mi potresti postare un pò di codice per capire , praticamente come hai fatto? Non mi è chiaro se l'hai calcolato matematicamente , in base alle righe del datagrid, ho se hai effettuato una prima volta il ciclo esterno alla routine print page, per poi chiamarla.
Grazie in anticipo dei chiarimenti.
Sergio
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5