Oh, che bello, la nostra applicazione (che però non vi
ho ancora fatto vedere!! ) produce la nostra stampa, che mostra
l'elenco di tutti i compleanni che abbiamo inserito nella ListBox. Se abbiamo
scritto il codice correttamente, quando clicchiamo sul button
btnPrint appare l'anteprima di stampa, con l'header, il footer
e il contenuto nella parte centrale del report. Non solo, usando l'attribute Logo che ho creato,
posso mettere anche una bella immagine in alto a destra. Spero di poter
mettere on-line il codice durante il weekend.
Comunque sia, io personalmente non sono ancora soddisfatto. Perchè?
Un'applicazione che si rispetti innanzitutto ha un bel menù (in .NET la classe è
MainMenu ); non solo, le
funzioni di stampa (provate ad aprire Word) sono di solito tre: Imposta Pagina, Anteprima
di Stampa e Stampa. Noi non l'abbiamo ancora fatto, lo faremo
oggi.
Tieniamo a mente questo schema:
- Imposta Pagina si implementa con la classe
PageSetupDialog
- Anteprima di Stampa si implementa con la classe
PrintPreviewDialog
- Stampa si implementa con la classe PrintDialog
Come procediamo? Beh, per prima cosa creiamo il
MainMenu di cui parlavo prima. Lo faremo con l'IDE per andare
veloci, e daremo uno sguardo al codice che è stato creato. L'interfaccia
risultante la potete vedere in questo
screenshot: vi piace?
Parliamo un po'
del codice:
Ho creato una struttura di menù: mnuPageSetup,
mnuPrintPreview e mnuPrint, gestiti dai
corrispondenti eventi Click, ovvero:
private void mnuPageSetup_Click(object sender, System.EventArgs e)
{ }
private void mnuPrintPreview_Click(object sender, System.EventArgs e)
{ }
private void mnuPrint_Click(object sender, System.EventArgs e)
{ }
Vediamo per esempio il codice per l'anteprima di stampa,
che concettualmente è lo stesso che abbiamo visto nel post precedente dedicato ad MCAD.
private void mnuPrintPreview_Click(object sender, System.EventArgs e)
{
this.PageNumer = 0;
PrintPreviewDialog prnPreview = new PrintPreviewDialog();
prnPreview.UseAntiAlias = true;
prnPreview.Document = getPrintDocument();
prnPreview.ShowDialog();
}
Viene istanziato prnPreview, a cui viene associata la
property Document tramite la function
getPrintDocument(): cosa fa questa function? Beh, non fa
nient'altro che generare e restituire un'istanza PrintDocument
del documento che vogliamo mandare in stampa. E' lo stesso codice che abbiamo
visto nei post precedenti, implementato però in una function dedicata, perchè
viene utilizzata in diversi momenti, per cui...fin qua nulla di più, abbiamo
già visto come sfruttare l'anteprima senza grossi problemi. Passiamo ad
altro.
Se vogliamo far scegliere all'utente la stampa su cui produrre l'output,
dobbiamo usare la classe PrintDialog, ecco qua il codice:
private void mnuPrint_Click(object sender, System.EventArgs e)
{
PrintDialog prnDialog = new PrintDialog();
prnDialog.AllowSelection = true;
prnDialog.AllowSomePages = true;
prnDialog.Document = getPrintDocument();
DialogResult result = prnDialog.ShowDialog();
if (result == DialogResult.OK)
prnDialog.Document.Print();
prnDialog.Dispose();
}
Istanziamo prnDialog, abilitiamo all'utente la
possibilità di decidere quali pagine stampare, valorizziamo la property
Document (notare l'uso di getPrintDocument()).
Chiamiamo il metodo ShowDialog(), e se l'utente risponde con
Ok, allora lanciamo fisicamente la stampa: questa volta non
avverrà più sulla stampante di default, ma su quella seleziona dall'utente nella
finestra di dialogo.
E, per ultimo, il codice per implementare l'Imposta Pagina. Eccolo:
private void mnuPageSetup_Click(object sender, System.EventArgs e)
{
PageSetupDialog prnPageSetupDialog = new PageSetupDialog();
prnPageSetupDialog.PageSettings = prnPageSettings;
prnPageSetupDialog.PrinterSettings = prnPageSettings.PrinterSettings;
prnPageSetupDialog.ShowNetwork = true;
DialogResult result = prnPageSetupDialog.ShowDialog();
if (result == DialogResult.OK)
{
prnPageSettings = prnPageSetupDialog.PageSettings;
prnPageSettings.PrinterSettings = prnPageSettings.PrinterSettings;
}
prnPageSetupDialog.Dispose();
}
Usando la classe
PageSetupDialog, memorizzo nell'istanza
prnPageSetupDialog tutte le impostazioni che l'utente vuole,
come margini, orientamento del foglio, etc. etc. Qui mi sono complicato la vita,
per esempio: prima di mostrare la finestra di dialogo a video (metodo
ShowDialog() anche qui), faccio in modo che quando verrà
aperta, essa visualizzerà i valori correnti del sistema (per farlo, uso il
membro privato della WF prnPageSettings, che viene dichiarato
ed inizializzato precedentemente). Se l'utente chiude la finestra con
Ok, allora salvo in prnPageSettings le nuove
impostazioni. Piccola annotazione: MSDN
ci dice letteralmente che: "The PageSetupDialog dialog box modifies the
PageSettings and PrinterSettings information for a given Document". Questo
significa che le impostazioni di stampa fanno parte della classe
PrintDocument, ovvero sono specifiche per ogni documento che
voglio stampare.
Adesso, conclusione, vediamo il codice della function
getPrintDocument(), che viene richiamata dagli eventi Click
degli Item del menù che abbiamo visto prima. Il suo codice è il seguente:
private PrintDocument getPrintDocument()
{
PrintDocument prnDoc = new PrintDocument();
prnDoc.PrintPage += new PrintPageEventHandler(this.printBirthday);
prnDoc.DocumentName = resMan.GetString("TITLE_DOCUMENT");
this.TotalPage = this.lstResults.Items.Count / this.LinePerPage;
if (this.TotalPage == 0) this.TotalPage = 1;
prnDoc.DefaultPageSettings = prnPageSettings;
prnDoc.PrinterSettings = prnPageSettings.PrinterSettings;
return (prnDoc);
}
Se ci fate caso, assomiglia all'evento btnPrint_Click
del post precedente, con due piccole differenze.
Primo: è stato appunto isolato in una function specifica (che restituisce
l'oggetto PrintDocument da stampare). Secondo: prima di ritornare l'istanza
PrintDocument imposto le property DefaultPageSettings e
PrinterSettings secondo quando contiene
prnPageSettings (quest'ultima contiene i valori di default di
sistema, oppure e impostazioni scelte dall'utente attraverso PageSetupDialog).
In questo modo, quando stamperò il documento (o ne visualizzerò l'anteprima) il
documento apparirà secondo le impostazioni scelte dall'utente attraverso il page
setup.
Ai fini di MCAD, direi che per quanto riguarda la gestione delle stampe
abbiamo finito.
Ricordiamoci quindi (a memoria!!!) PageSetupDialog,
PrintDialog e PrintPreviewDialog. Ricordiamoci
che tutte e tre hanno il metodo ShowDialog per interagire con
l'utente, ricordiamoci la property Document e impariamo un
po' la classe PrintDocument (che indipendentemente da
tutto, è l'oggetto più importante, perchè è quello che contiene il documento
vero e proprio)
- la property DocumentName
- la property PrinterSettings
- il metodo Print()
- l'evento PrintPage
- l'handler private void printBirthday(object sender, PrintPageEventArgs
ev)
powered by IMHO 1.2