La stampa dei controlli in VB.Net e C#

Tecnica per effettuare la stampa dei controlli di una windows Form.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

Introduzione

Continua la serie di articoli dedicati all’utilizzo della stampa in .Net 4, tramite i linguaggi di programmazione VB.Net e C#. In questo articolo,  vedremo come stampare in una form, i controlli presenti nella finestra.
Dopo aver creato un nuovo progetto di tipo “Windows Application” inseriamo nella form, un controllo groupbox, due pulsanti, due controlli label, due controlli caselle di testo e tre controlli di tipo checkbox.
Il tutto come mostrato in figura 1




Figura 1

Terminata la parte di disegno della nostra finestra, passiamo in visualizzazione codice.
Inseriamo lo spazio dei nomi per la stampa, il tutto come mostrato qui di seguito.
VB.Net
Imports System.Drawing.Printing
C#
using System.Drawing.Printing;


Dopo la dichiarazione di form, scriviamo le variabili oggetto per gestire la stampa.
Qui di seguito si riportano i codice per entrambi i linguaggi.
VB.Net
'variabile per la gestione del documento di stampa
    Private WithEvents m_pdcStampa As New PrintDocument()
    'variabile per l'anteprima
    Private m_ppdAnteprima As New PrintPreviewDialog()
    'variabile per la gestine delle distanze dei controlli
    Dim IntLeft As Integer = 150
    Dim IntTop As Integer = 50
C#
  //variabile per la gestione del documento di stampa
        PrintDocument m_pdcStampa = new PrintDocument();
        //variabile per l'anteprima
        PrintPreviewDialog m_ppdAnteprima = new PrintPreviewDialog();
        //variabile per la gestine delle distanze dei controlli
        int IntLeft = 150;
        int IntTop = 50;



A differenza del linguaggio VB.Net, per l’esempio C#. nell’evento load della form, scriviamo il codice per la gestione dell’evento printpage.
Il tutto come mostrato qui di seguito.
C#
  private void Form1_Load(object sender, EventArgs e)
        {
            m_pdcStampa.PrintPage += new PrintPageEventHandler(m_pdcStampa_PrintPage);
        }


Terminata la stesura di codice, scriviamo il codice per gestire la stampa dei controlli. La funzione preposta qui di seguito, illustra una tecnica che predispone la stampa e l’anteprima di stampa, riguardante la form con i relativi controlli

VB.Net
  Private Sub StampaControllo(ByVal BlnCheckbox As Boolean, ByVal blnDisegnaBordo As Boolean, ByVal ClrColoreBordo As Color, _
    ByVal IntTopControllo As Integer, ByVal IntLeftControllo As Integer, ByVal CtrControllo As Control, ByVal grp As Graphics, _
    ByVal Allienamento As StringAlignment)
        Dim PenBordo As New Pen(ClrColoreBordo)
        'dimensione
        Dim Rect As New RectangleF(CtrControllo.Left + IntLeftControllo, CtrControllo.Top + IntTopControllo, CtrControllo.Width, CtrControllo.Height)
        'verifica se deve disegnare il bordo
        If blnDisegnaBordo Then
            grp.DrawRectangle(PenBordo, Rect.Left, Rect.Top, CtrControllo.Width, CtrControllo.Height)
        End If
        'qualora la è true il blncheckbox è una check faccio altre operazioni
        If BlnCheckbox = True Then
            'misure per margine top e sinistro
            Dim intTopCheckBox As Integer = Rect.Top + (Rect.Height / 2) - 5
            Dim IntLeftCheckbox As Integer = Rect.Left + 5
            Dim chkMioCheckbox As CheckBox = CType(CtrControllo, CheckBox)
            grp.DrawRectangle(PenBordo, IntLeftCheckbox, intTopCheckBox, 10, 10)
            If chkMioCheckbox.CheckState = CheckState.Checked Then
                grp.FillRectangle(New SolidBrush(Color.Blue), IntLeftCheckbox + 2, intTopCheckBox + 2, 6, 6)
            End If
            'disegno il testo
            grp.DrawString(CtrControllo.Text, Me.Font, New SolidBrush(Color.Black), Rect.Left + 18, Rect.Top)
        Else
            'allienamento del testo
            Dim fm As New StringFormat(StringFormatFlags.LineLimit)
            fm.Alignment = Allienamento
            'disegno il testo
            grp.DrawString(CtrControllo.Text, Me.Font, New SolidBrush(Color.Black), Rect, fm)
        End If
        'rilascia la memoria
        PenBordo.Dispose()
    End Sub
C#
private void StampaControllo(bool BlnCheckbox, bool blnDisegnaBordo, Color ClrColoreBordo, int IntTopControllo, int IntLeftControllo, Control CtrControllo, Graphics grp, StringAlignment Allienamento)
        {
            Pen PenBordo = new Pen(ClrColoreBordo);
            //dimensione
            RectangleF Rect = new RectangleF(CtrControllo.Left + IntLeftControllo, CtrControllo.Top + IntTopControllo, CtrControllo.Width, CtrControllo.Height);
            //verifica se deve disegnare il bordo
            if (blnDisegnaBordo)
                grp.DrawRectangle(PenBordo, Rect.Left, Rect.Top, CtrControllo.Width, CtrControllo.Height);
            //qualora la è true il blncheckbox è una check faccio altre operazioni
            if (BlnCheckbox == true)
            {
                //misure per margine top e sinistro
                int intTopCheckBox = Convert.ToInt32((Rect.Top + (Rect.Height / 2) - 5));
                int IntLeftCheckbox = Convert.ToInt32((Rect.Left + 5));
                CheckBox chkMioCheckbox = (CheckBox)CtrControllo;
                grp.DrawRectangle(PenBordo, IntLeftCheckbox, intTopCheckBox, 10, 10);
                if (chkMioCheckbox.CheckState == CheckState.Checked)
                    grp.FillRectangle(new SolidBrush(Color.Blue), IntLeftCheckbox + 2, intTopCheckBox + 2, 6, 6);
                //disegno il testo
                grp.DrawString(CtrControllo.Text, this.Font, new SolidBrush(Color.Black), Rect.Left + 18, Rect.Top);
            }
            else
            {
                //allienamento del testo
                StringFormat fm = new StringFormat(StringFormatFlags.LineLimit);
                fm.Alignment = Allienamento;
                //disegno il testo
                grp.DrawString(CtrControllo.Text, this.Font, new SolidBrush(Color.Black), Rect, fm);
            }
            //rilascia la memoria
            PenBordo.Dispose();
        }


Ora scriviamo la funzione che permette di rilevare tutti i controlli presenti nella form. La funzione richiama quella precedente, per ogni controllo trovato.
Per i controlli contenitori, per esempio Groupbox, viene fatto un ciclo recursivo permettendo in questo modo di rilevare i controlli al suo interno.
Qui di seguito si riporta il codice.
VB.Net
    'Funzione per ricercare i controlli nel form
    Private Sub TrovaControlli(ByVal Grp As Graphics, ByVal CtrForm As Control)
        Dim CtrControlli As Control
        Dim IntTopIniziale As Integer = IntTop
        Dim intLefIniziale As Integer = IntLeft
        'verifico che non sia una form
        If Not (TypeOf CtrForm Is Form) Then
            IntTopIniziale = CtrForm.Top + IntTop
            intLefIniziale = CtrForm.Left + IntLeft
        End If
        'ciclo per tutti i controlli
        For Each CtrControlli In CtrForm.Controls
            If TypeOf CtrControlli Is CheckBox Then
                StampaControllo(True, False, Color.LightGray, IntTopIniziale, intLefIniziale, CtrControlli, Grp, StringAlignment.Near)
                'funzione se è un checkbox
            ElseIf TypeOf CtrControlli Is GroupBox Then
                StampaControllo(False, True, Color.LightGray, IntTopIniziale, intLefIniziale, CtrControlli, Grp, StringAlignment.Near)
                TrovaControlli(Grp, CtrControlli)
            Else
                StampaControllo(False, True, Color.LightGray, IntTopIniziale, intLefIniziale, CtrControlli, Grp, StringAlignment.Near)
                'funzione se non è di checkbox
            End If
        Next
    End Sub
C#
//Funzione per ricercare i controlli nella form
        private void TrovaControlli(Graphics Grp, Control CtrForm)
        {
            //Control CtrControlli;
            int IntTopIniziale = IntTop;
            int intLefIniziale = IntLeft;
            //verifico che non sia una form
            if (!(CtrForm is Form))
            {
                IntTopIniziale = CtrForm.Top + IntTop;
                intLefIniziale = CtrForm.Left + IntLeft;
            }
            //ciclo per tutti i controlli
            foreach (Control CtrControlli in CtrForm.Controls)
            {
                if (CtrControlli is CheckBox)
                    StampaControllo(true, false, Color.LightGray, IntTopIniziale, intLefIniziale, CtrControlli, Grp, StringAlignment.Near);
                else if (CtrControlli is GroupBox)
                {
                    StampaControllo(false, true, Color.LightGray, IntTopIniziale, intLefIniziale, CtrControlli, Grp, StringAlignment.Near);
                    TrovaControlli(Grp, CtrControlli);
                }
                else
                    StampaControllo(false, true, Color.LightGray, IntTopIniziale, intLefIniziale, CtrControlli, Grp, StringAlignment.Near);
            }
        }

Scriviamo il codice per il gestore di evento “PrintPage” della classe “Prindocument” permettendo in questo modo di eseguire la funzione “TrovaControlli” per predisporre la stampa.

VB.Net
Private Sub m_pdcStampa_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles m_pdcStampa.PrintPage
        TrovaControlli(e.Graphics, Me)
        e.Graphics.DrawRectangle(Pens.Green, IntLeft, IntTop, Width, Height)
        e.Graphics.FillRectangle(New SolidBrush(SystemColors.ActiveCaption), IntLeft, IntTop, Width, 10)
        e.HasMorePages = False
    End Sub
C#
  private void m_pdcStampa_PrintPage(object sender, PrintPageEventArgs e)
        {
            TrovaControlli(e.Graphics, this);
            e.Graphics.DrawRectangle(Pens.Green, IntLeft, IntTop, Width, Height);
            e.Graphics.FillRectangle(new SolidBrush(SystemColors.ActiveCaption), IntLeft, IntTop, Width, 10);
            e.HasMorePages = false;
        }

Siamo giunti alla conclusione del codice, ora non resta che scrivere il codice riguardante l’evento click del pulsante di stampa.
In questo evento, scriveremo il codice riguardante l’impostazione di stampa, come dimensini, posizione della finestra, ed altro ancora.
VB.Net
Private Sub btnStampa_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStampa.Click
        With ppdAnteprima
            .Width = 640
            .Height = 480
            'toglie la popup
            m_pdcStampa.PrintController = New System.Drawing.Printing.StandardPrintController()
            .Document = m_pdcStampa
            .StartPosition = FormStartPosition.CenterScreen
            .ShowDialog(Me)
        End With
    End Sub
C#
   private void btnStampa_Click(object sender, EventArgs e)
        {
            ppdAnteprima.Width = 640;
            ppdAnteprima.Height = 480;
            //toglie la popup
            m_pdcStampa.PrintController = new StandardPrintController();
            ppdAnteprima.Document = m_pdcStampa;
            ppdAnteprima.StartPosition = FormStartPosition.CenterScreen;
            ppdAnteprima.ShowDialog(this);
        }

Conclusioni


L’articolo ha voluto fornire al lettore una tecnica di come stampare una form con i relativi controlli.
Nel prossimo ed ultimo articolo, vedremo la stampa di un controllo GridView.
Tramite la parola Download è possibile scaricare il file d’esempio utilizzato in questo articolo.

Download