Printable ListView

Introduction

Sometimes in my development work, I needed to print the contents of a ListView control. So, I wrote down the code for a custom control, named PrintableListView, that solves the following two problems:

  • Extends the print on multiple pages when the width of the list exceeds the width of the print page.
  • Shrinks, optionally, the list in a way that the resulting width fits on a single page.

Using the Code

The PrintableListView control is derived from System.Windows.Forms.ListView, so use it like the native ListView control. The additional functionalities are those for print and for print preview.

// call the print method for displaying the standard print dialog.
this.m_list.Print();

// call the print preview method for displaying the standard print
// preview dialog
this.m_list.PrintPreview();

To turn on the "Fit to page" option, use the FitToPage property of the control.

this.m_list.FitToPage = true;

To set the title that appear on the page header, use the Title property of the control.

Points of Interest

If you think about the ListView control, you will note that you have all the information you need to print it in the simplest way. You have the columns' widths, the fonts, the rows' heights, and so on. All you have to do is to get all this information and play a little with the Graphics instance that represents the printing surface. What follows is the way I solved the problems listed in the Introduction.

Multi page print

This is quite simple. When you print the current column of a row, check whether there is enough room to print it. If not, mark that column as the first one for the next page. That's it.

Fit to page

This point is just a little bit more complex compared to the previous one. If the total width of the list is greater than the width of the available space, you have to calculate a scaling factor, given by the list width divided by the available space. For simplicity, in my implementation, I converted all the measures in units of hundredths of an inch. Setting the scale factor and unit of measure is sufficient to change the coordinate system of the Graphics object passed to the handler of the PrintPage event of the PrintDocument object.

private void OnPrintPage(object sender, PrintPageEventArgs e)
{
   b&
   b&
   if (m_nStartCol==0 && m_bFitToPage
                      && m_fListWidth>rectBody.Width)
   {
      // Calculate scale factor
      fScale = rectBody.Width / m_fListWidth;
   }
   b&
   b&
   // Setting scale factor and unit of measure
   g.ScaleTransform(fScale, fScale);
   g.PageUnit = GraphicsUnit.Inch;
   g.PageScale = 0.01f;
   b&
}


About the Author

Matteo D'Avena

I am from Apricena, a small town in Puglia, Italy. I graduated at the University of Bari in 1998 in Computer Science. I worked for seven years in the field of business intelligence with one of the most important italian group producing software and services for the banking and financial sector. Now I am a freelance software developer and consultant. I developed a product, GipsyReports - Visual Reporting System, that you can download, in demo version, from my personal web site: http://www.webalice.it/matteo.davena/en. GipsyReports application is localizable in Italian and English languages. For any further information about GipsyReports or custom developments, feel free to contact me at the address: matteo.davena@alice.it. I am very interested in your opinion about this product.

Downloads