Stampa su più pagine con PrintDocument

venerdì 11 dicembre 2009 - 17.09

volperubbia Profilo | Senior Member

Ciao a tutti,
ho una piccola applicazione VB.NET 2005 e vorrei realizzare qualche semplice stampa da codice,
senza ricorrere a componenti esterni (senza cioè itextsharp / crystal reports / reporting services,
che sono le soluzioni da me adottate in altri progetti).
Pensavo a una soluzione tipo quella in allegato, un form ereditato da PrintPreviewDialog che posso
poi richiamare con

Using obj As New frmPrint
obj.TipoStampa = ...
obj.ShowDialog()
End Using

Una cosa che non ho ben capito è come usare HasMorePages ... Nell'esempio allegato, ho un
PrintedPages che alla fine vale due, ma il risultato finale è due cicli di stampa sulla stessa
pagina, anzichè due pagine. Dove sbaglio, bisogna forse richiamare più volte PrintPage
in qualche modo?

Altro dubbio ... per quanto riguarda la stampa vera e propria, cliccando sull'icona stampa
di frmPrint, è possibile far aprire un PrintDialog prima dell'invio diretto alla stampante?

Grazie per l'attenzione,
Davide

AntCiar Profilo | Expert

ciao.

Io ho usato il PrintDocument per effettuare la stampa dei dati contenuti in una listView.
Dai una occhiata al codice seguente così e puoi trarre spunto.
Ciao ciao

private void PrintDocument1_PrintPage_1(object sender, PrintPageEventArgs ev)
{
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
float xstart = 0;
bool ColoreTxt = this.ColoreTestoCH.Checked;
bool ColoreSfn = this.ColoreSfondoCH.Checked;
float ColumnDim = 0;
bool VertColAdd = false;
Brush brs;

_pageWidt = ev.MarginBounds.Width;

if (this.checkBox1.Checked == true)
{
topMargin = topMargin + 60;
}

// Calculate the number of lines per page.
if (checkBox1.Checked == false)
{
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics);
}
else
{
linesPerPage = (ev.MarginBounds.Height - 60) / printFont.GetHeight(ev.Graphics);
}

// creazione degli elementi di stampa
while (count < linesPerPage && itemIndex < this.lst.Items.Count)
{
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
xstart = leftMargin;

if (itemIndex == -1)
{
if (this.checkBox1.Checked == true)
{
ev.Graphics.DrawString(this.IntestazioneTB.Text, new Font(printFont.Name, 13, FontStyle.Bold), Brushes.Black, new RectangleF(xstart, yPos - 50, ev.MarginBounds.Width, 40));
}

//Intestazioni di colonna
for (int c = 0; c < this.lst.Columns.Count; c++)
{
if (this.useListIcons_ == true)
{
if (c == 1)
{
xstart = xstart + printFont.GetHeight(ev.Graphics) + 2;
}
}

ColumnDim = this.GetDimensioneColonna(c);
if (ColumnDim > 0)
{
ev.Graphics.DrawString(this.lst.Columns[c].Text, printFont, new SolidBrush(intestColumnColor), new RectangleF(xstart, yPos, ColumnDim, printFont.GetHeight(ev.Graphics)));
xstart = xstart + ColumnDim;
}
}
count++;

//Aggiungo la linea orizzontale di separazione tra colonne e dati
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics)) + 2;
ev.Graphics.DrawLine(new Pen(intestColumnColor, 2), new Point((int)ev.MarginBounds.Left, (int)yPos), new Point((int)ev.MarginBounds.Right, (int)yPos));

count++;
this.itemIndex++;
}

yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
xstart = leftMargin;

//Eventuale inserimento delle icone
if (this.useListIcons_ == true)
{
ev.Graphics.DrawImage(this.lst.Items[this.itemIndex].ImageList.Images[this.lst.Items[this.itemIndex].ImageIndex], xstart, yPos, printFont.GetHeight(ev.Graphics), printFont.GetHeight(ev.Graphics));
xstart = xstart + printFont.GetHeight(ev.Graphics) + 2;
}


for (int c = 0; c < this.lst.Columns.Count; c++)
{
ColumnDim = this.GetDimensioneColonna(c);
if (ColumnDim > 0)
{
if (ColoreSfn == true)
{
brs = new SolidBrush(this.lst.Items[this.itemIndex].SubItems[c].BackColor);
ev.Graphics.FillRectangle(brs, new RectangleF(xstart, yPos, this.GetDimensioneColonna(c), printFont.GetHeight(ev.Graphics)));
}

brs = Brushes.Black;
if (ColoreTxt == true)
{
brs = new SolidBrush(this.lst.Items[this.itemIndex].SubItems[c].ForeColor);
}

ev.Graphics.DrawString(this.lst.Items[this.itemIndex].SubItems[c].Text, printFont, brs, new RectangleF(xstart, yPos, ColumnDim, printFont.GetHeight(ev.Graphics)));
xstart = xstart + ColumnDim;
}
}

count++;
this.itemIndex++;
}

//Inserimento delle linee verticali
if (this.drawVerticalLine == true)
{
if (VertColAdd == false)
{
xstart = leftMargin;

//Disegno la linea di inizio colonna
// ev.Graphics.DrawLine(Pens.Black, new Point((int)xstart - 2, (int)topMargin), new Point((int)xstart - 2, (int)ev.MarginBounds.Bottom));

if (this.useListIcons_ == true)
{
xstart = xstart + printFont.GetHeight(ev.Graphics) + 2;
}
for (int c = 0; c < this.lst.Columns.Count; c++)
{
ColumnDim = this.GetDimensioneColonna(c);
if (ColumnDim > 0)
{
if (c != this.lst.Columns.Count - 1)
{
xstart = xstart + ColumnDim;
ev.Graphics.DrawLine(Pens.Black, new Point((int)xstart, (int)topMargin), new Point((int)xstart, (int)ev.MarginBounds.Bottom));
}

}
}

VertColAdd = true;
}
}

// If more lines exist, print another page.
if (itemIndex < this.lst.Items.Count)
ev.HasMorePages = true;
}
Cristian Barca

volperubbia Profilo | Senior Member

Ciao Cristian, grazie.
Ora l'evento PrintPage funziona correttamente e stampa su nuova pagina,
è bastato tenersi il numero di riga corrente CurrentRow e impostare un
exit for dopo e.HasMorePages = True.
In questo modo, avanza di una pagina e riprende a stampare dalla riga
corrente.

Vedi l'allegato 1221_frmPrint_02.zip.

Per il seconto aspetto, richiamare PrintDialog prima dell'invio in stampa,
ci sto lavorando. Forse la soluzione è mostrargli PrintDialog prima di
frmPrint ... vedremo ...

Davide
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