Skip to content

Latest commit

 

History

History
207 lines (181 loc) · 7.79 KB

12 - WinForms - Printing.md

File metadata and controls

207 lines (181 loc) · 7.79 KB

Windows Forms – Printing

1. Objectives

  • using the PrintPreviewDialog, PrintDialog and PageSetupDialog dialogs;
  • printing text and shapes;
  • printing a document that exceeds a single page;

2. Printing

Activity

:octocat: Sample Code available – Check the “PrintingRecordsSample” Sample

  1. Create a copy of the “ListViewBasicSample” project and name it “PrintingRecordsSample”

  2. Add a MenuStrip control with the options shown in the following screenshot Printing Sample

  3. From the ToolBox add a PrintDocument control and name it printDocument.

  4. From the ToolBox add a PageSetupDialog control and name it pageSetupDialog. For the Document property of the pageSetupDialog choose the printDocument.

  5. Handle the Click event on the "PageSetup" button as follows

    private void btnPageSetup_Click(object sender, EventArgs e)
    {
        pageSetupDialog.PageSettings = printDocument.DefaultPageSettings;
    
        if (pageSetupDialog.ShowDialog() == DialogResult.OK)
            printDocument.DefaultPageSettings = pageSetupDialog.PageSettings;
    }
  6. Handle the PrintPage event of the PrintDocument control as follows

    private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        // Initialize the font to be used for printing.
        Font font = new Font("Microsoft Sans Serif", 24);
    
        var pageSettings = e.PageSettings;
        
        // Initialize local variables that contain the bounds of the printing area rectangle.
        //var printAreaHeight = pageSettings.PaperSize.Height - pageSettings.Margins.Top - pageSettings.Margins.Bottom;
        //or
        var printAreaHeight = e.MarginBounds.Height;
    
        //var printAreaWidth = pageSettings.PaperSize.Width - pageSettings.Margins.Left - pageSettings.Margins.Right;
        //or
        var printAreaWidth = e.MarginBounds.Width;
    
        // Initialize local variables to hold margin values that will serve
        // as the X and Y coordinates for the upper left corner of the printing 
        // area rectangle.
        var marginLeft = pageSettings.Margins.Left;
        // X coordinate
        var marginTop = pageSettings.Margins.Top;
        // Y coordinate
    
        // If the user selected Landscape mode, swap the printing area height 
        // and width.
        if (pageSettings.Landscape)
        {
            var intTemp = printAreaHeight;
            printAreaHeight = printAreaWidth;
            printAreaWidth = intTemp;
        }
    
        const int rowHeight = 40;
        var columnWidth = printAreaWidth / 3;
    
        // Instantiate the StringFormat class, which encapsulates text layout 
        // information (such as alignment and line spacing), display manipulations 
        // (such as ellipsis insertion and national digit substitution) and OpenType 
        // features. Use of StringFormat causes MeasureString and DrawString to use
        // only an integer number of lines when printing each page, ignoring partial
        // lines that would otherwise likely be printed if the number of lines per 
        // page do not divide up cleanly for each page (which is usually the case).
        // See further discussion in the SDK documentation about StringFormatFlags.
        StringFormat fmt = new StringFormat(StringFormatFlags.LineLimit);
        fmt.Trimming = StringTrimming.EllipsisCharacter;
    
        var currentY = marginTop;
        while(_currentParticipantIndex < _participants.Count)
        {
            //Reset the horizontal drawing coordinate
            var currentX = marginLeft;
    
            //Draw the border of the cell
            e.Graphics.DrawRectangle(
                Pens.Black, 
                currentX, 
                currentY, 
                columnWidth, 
                rowHeight);
            //Draw the text in the cell
            /*e.Graphics.DrawString(
                _participants[i].FirstName,
                font,
                Brushes.Black,
                currentX,
                currentY,
                fmt);*/
            // By specifying a LayoutRectangle, we are forcing the text into a specific area, with automatic word wrapping and other features controllable through the StringFormat parameter
            e.Graphics.DrawString(
                _participants[_currentParticipantIndex].LastName,
                font,
                Brushes.Black,
                new RectangleF(currentX, currentY, columnWidth, rowHeight),
                fmt);
            //Update the horizontal drawing coordinate
            currentX += columnWidth;
    
            e.Graphics.DrawRectangle(
                Pens.Black,
                currentX,
                currentY,
                columnWidth,
                rowHeight);
            e.Graphics.DrawString(
                _participants[_currentParticipantIndex].FirstName,
                font,
                Brushes.Black,
                currentX,
                currentY,
                fmt);
            currentX += columnWidth;
    
            e.Graphics.DrawRectangle(
                Pens.Black,
                currentX,
                currentY,
                columnWidth,
                rowHeight);
            e.Graphics.DrawString(
                _participants[_currentParticipantIndex].BirthDate.ToShortDateString(),
                font,
                Brushes.Black,
                currentX,
                currentY,
                fmt);
    
            //Update the participant index
            _currentParticipantIndex++;
            //Update the vertifcal drawing coordinate
            currentY += rowHeight;
    
            // HasMorePages tells the printing module whether another PrintPage event should be fired.
            if (currentY + rowHeight > printAreaHeight)
            {
                e.HasMorePages = true;
                break;
            }
        }
    }
  7. Handle the BeginPrint event of the PrintDocument control as follows

    private void printDocument_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        _currentParticipantIndex = 0;
    }
  8. From the ToolBox add a PrintPreviewDialog and name it printPreviewDialog.

  9. For the Document property of the printPreviewDialog choose the printDocument.

  10. Handle the Click event on the "PrintPreview" button, as follows

    private void btnPrintPreview_Click(object sender, EventArgs e)
    {
        try
        {
            printPreviewDialog.ShowDialog();
        }
        catch (Exception)
        {
            MessageBox.Show("An error occurred while trying to load the document for Print Preview. Make sure you currently have access to a printer. A printer must be connected and accessible for Print Preview to work.");
        }
    }
  11. From the ToolBox add a PrintDialog and name it printDialog.

  12. For the Document property of the printDialog choose the printDocument.

  13. Handle the Click event on the "Print" button as follows

    private void btnPrint_Click(object sender, EventArgs e)
    {
        if (printDialog.ShowDialog() == DialogResult.OK)
            printDocument.Print();
    }

Assignment (for you to try)

  1. Add a header at the begging of the printed report
  2. Repeat the header at the beginning of each new page

Activity

:octocat: Sample Code available – Check the “PrintingLongTextSample” Sample

Printing Sample

3. Bibliography