Introduction
Some time during my development works I had the need of printing the contents of a ListView
control. So I wrote down the code for a custom control, named PrintableListView
, that solved the following two problems:
- extend the print on multiple pages when the width of the list exceeds the width of the print page,
- shrink, optionally, the list in a way that the resulting width fits on a single page.
Using the code
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.
this.m_list.Print();
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 appears 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 we have all the information we need to print it in the simplest way. We have the columns width, the fonts, the rows height and so on. All we have to do is to get all these 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 we are printing the current column of a row, we check whether there is enough room to print it. If not, we 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, we 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. To set 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)
{
…
if (m_nStartCol==0 && m_bFitToPage && m_fListWidth>rectBody.Width)
{
fScale = rectBody.Width / m_fListWidth;
}
…
…
g.ScaleTransform(fScale, fScale);
g.PageUnit = GraphicsUnit.Inch;
g.PageScale = 0.01f;
…
}