using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Drawing.Printing; using System.Drawing.Drawing2D; namespace PrintableListView { /// /// Summary description for PrintableListView. /// public class PrintableListView : System.Windows.Forms.ListView { // Print fields private PrintDocument m_printDoc = new PrintDocument(); private PageSetupDialog m_setupDlg = new PageSetupDialog(); private PrintPreviewDialog m_previewDlg = new PrintPreviewDialog(); private PrintDialog m_printDlg = new PrintDialog(); private int m_nPageNumberC = 1; private int m_nPageNumber=1; private int m_nStartRow=0; private int m_nStartCol=0; private bool m_bPrintSel=false; private bool m_bFitToPage=false; private float m_fListWidth=0.0f; private float[] m_arColsWidth; private float m_fDpi=96.0f; private string m_strTitle=""; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; #region Properties /// /// Gets or sets whether to fit the list width on a single page /// /// /// True if you want to scale the list width so it will fit on a single page. /// /// /// If you choose false (the default value), and the list width exceeds the page width, the list /// will be broken in multiple page. /// public bool FitToPage { get {return m_bFitToPage;} set {m_bFitToPage=value;} } /// /// Gets or sets the title to dispaly as page header in the printed list /// /// /// A the represents the title printed as page header. /// public string Title { get {return m_strTitle;} set {m_strTitle=value;} } #endregion public PrintableListView() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); m_printDoc.BeginPrint += new PrintEventHandler(OnBeginPrint); m_printDoc.PrintPage += new PrintPageEventHandler(OnPrintPage); m_setupDlg.Document = m_printDoc; m_previewDlg.Document = m_printDoc; m_printDlg.Document = m_printDoc; m_printDlg.AllowSomePages = false; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion /// /// Show the standard page setup dialog box that lets the user specify /// margins, page orientation, page sources, and paper sizes. /// public void PageSetup() { m_setupDlg.ShowDialog(); } /// /// Show the standard print preview dialog box. /// public void PrintPreview() { m_printDoc.DocumentName = "List View"; m_nPageNumber = 1; m_bPrintSel = false; m_previewDlg.FindForm().WindowState = FormWindowState.Maximized; m_previewDlg.ShowDialog(this); } /// /// Start the print process. /// public void Print() { m_printDlg.AllowSelection = this.SelectedItems.Count>0; // Show the standard print dialog box, that lets the user select a printer // and change the settings for that printer. if (m_printDlg.ShowDialog(this) == DialogResult.OK) { m_printDoc.DocumentName = m_strTitle; m_bPrintSel = m_printDlg.PrinterSettings.PrintRange==PrintRange.Selection; m_nPageNumber = 1; // Start print m_printDoc.Print(); } } #region Events Handlers private void OnBeginPrint(object sender, CancelEventArgs e) { PreparePrint(); } private void OnPrintPage(object sender, PrintPageEventArgs e) { int nNumItems = GetItemsCount(); // Number of items to print if (nNumItems==0 || m_nStartRow>=nNumItems) { e.HasMorePages = false; return; } int nNextStartCol = 0; // First column exeeding the page width float x = 0.0f; // Current horizontal coordinate float y = 0.0f; // Current vertical coordinate float cx = 4.0f; // The horizontal space, in hundredths of an inch, // of the padding between items text and // their cell boundaries. float fScale = 1.0f; // Scale factor when fit to page is enabled float fRowHeight = 0.0f; // The height of the current row float fColWidth = 0.0f; // The width of the current column RectangleF rectFull; // The full available space RectangleF rectBody; // Area for the list items bool bUnprintable = false; Graphics g = e.Graphics; if (g.VisibleClipBounds.X<0) // Print preview { rectFull = e.MarginBounds; // Convert to hundredths of an inch rectFull = new RectangleF(rectFull.X/m_fDpi*100.0f, rectFull.Y/m_fDpi*100.0f, rectFull.Width/m_fDpi*100.0f, rectFull.Height/m_fDpi*100.0f); } else // Print { // Printable area (approximately) of the page, taking into account the user margins rectFull = new RectangleF( e.MarginBounds.Left - (e.PageBounds.Width - g.VisibleClipBounds.Width)/2, e.MarginBounds.Top - (e.PageBounds.Height - g.VisibleClipBounds.Height)/2, e.MarginBounds.Width, e.MarginBounds.Height); } rectBody = RectangleF.Inflate(rectFull, 0, -2*Font.GetHeight(g)); // Display title at top StringFormat sfmt = new StringFormat(); sfmt.Alignment = StringAlignment.Center; g.DrawString(m_strTitle, Font, Brushes.Black, rectFull, sfmt); // Display page number at bottom sfmt.LineAlignment = StringAlignment.Far; g.DrawString("Page " + m_nPageNumber, Font, Brushes.Black, rectFull, sfmt); if (m_nStartCol==0 && m_bFitToPage && m_fListWidth>rectBody.Width) { // Calculate scale factor fScale = rectBody.Width / m_fListWidth; } // Scale the printable area rectFull = new RectangleF(rectFull.X/fScale, rectFull.Y/fScale, rectFull.Width/fScale, rectFull.Height/fScale); rectBody = new RectangleF(rectBody.X/fScale, rectBody.Y/fScale, rectBody.Width/fScale, rectBody.Height/fScale); // Setting scale factor and unit of measure g.ScaleTransform(fScale, fScale); g.PageUnit = GraphicsUnit.Inch; g.PageScale = 0.01f; // Start print nNextStartCol=0; y = rectBody.Top; // Columns headers ---------------------------------------- Brush brushHeader = new SolidBrush(Color.LightGray); Font fontHeader = new Font(this.Font, FontStyle.Bold); fRowHeight = fontHeader.GetHeight(g)*3.0f; x = rectBody.Left; for (int i=m_nStartCol; irectBody.Bottom) { bEndOfPage=true; } else { x = rectBody.Left; for (int i=m_nStartCol; i0 && m_nStartRow0); if (!e.HasMorePages) { m_nPageNumber=1; m_nStartRow=0; m_nStartCol=0; } brushHeader.Dispose(); } #endregion private int GetItemsCount() { return m_bPrintSel ? SelectedItems.Count : Items.Count; } private ListViewItem GetItem(int index) { return m_bPrintSel ? SelectedItems[index] : Items[index]; } private void PreparePrint() { // Gets the list width and the columns width in units of hundredths of an inch. this.m_fListWidth = 0.0f; this.m_arColsWidth = new float[this.Columns.Count]; Graphics g = CreateGraphics(); m_fDpi = g.DpiX; g.Dispose(); for (int i=0; i