using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
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_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.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, PrintEventArgs 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; i < Columns.Count; i++)
{
ColumnHeader ch = Columns[i];
fColWidth = m_arColsWidth[i];
if ((x + fColWidth) <= rectBody.Right)
{
// Rectangle
g.FillRectangle(brushHeader, x, y, fColWidth, fRowHeight);
g.DrawRectangle(Pens.Black, x, y, fColWidth, fRowHeight);
// Text
StringFormat sf = new StringFormat();
if (ch.TextAlign == HorizontalAlignment.Left)
sf.Alignment = StringAlignment.Near;
else if (ch.TextAlign == HorizontalAlignment.Center)
sf.Alignment = StringAlignment.Center;
else
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Center;
sf.FormatFlags = StringFormatFlags.NoWrap;
sf.Trimming = StringTrimming.EllipsisCharacter;
RectangleF rectText = new RectangleF(x + cx, y, fColWidth - 1 - 2 * cx, fRowHeight);
g.DrawString(ch.Text, fontHeader, Brushes.Black, rectText, sf);
x += fColWidth;
}
else
{
if (i == m_nStartCol)
bUnprintable = true;
nNextStartCol = i;
break;
}
}
y += fRowHeight;
// Rows ---------------------------------------------------
int nRow = m_nStartRow;
bool bEndOfPage = false;
while (!bEndOfPage && nRow < nNumItems)
{
ListViewItem item = GetItem(nRow);
fRowHeight = item.Bounds.Height / m_fDpi * 100.0f + 5.0f;
if (y + fRowHeight > rectBody.Bottom)
{
bEndOfPage = true;
}
else
{
x = rectBody.Left;
for (int i = m_nStartCol; i < Columns.Count; i++)
{
ColumnHeader ch = Columns[i];
fColWidth = m_arColsWidth[i];
if ((x + fColWidth) <= rectBody.Right)
{
// Rectangle
g.DrawRectangle(Pens.Black, x, y, fColWidth, fRowHeight);
// Text
StringFormat sf = new StringFormat();
if (ch.TextAlign == HorizontalAlignment.Left)
sf.Alignment = StringAlignment.Near;
else if (ch.TextAlign == HorizontalAlignment.Center)
sf.Alignment = StringAlignment.Center;
else
sf.Alignment = StringAlignment.Far;
sf.LineAlignment = StringAlignment.Center;
sf.FormatFlags = StringFormatFlags.NoWrap;
sf.Trimming = StringTrimming.EllipsisCharacter;
// Text
string strText = i == 0 ? item.Text : item.SubItems[i].Text;
Font font = i == 0 ? item.Font : item.SubItems[i].Font;
RectangleF rectText = new RectangleF(x + cx, y, fColWidth - 1 - 2 * cx, fRowHeight);
g.DrawString(strText, font, Brushes.Black, rectText, sf);
x += fColWidth;
}
else
{
nNextStartCol = i;
break;
}
}
y += fRowHeight;
nRow++;
}
}
if (nNextStartCol == 0)
m_nStartRow = nRow;
m_nStartCol = nNextStartCol;
m_nPageNumber++;
e.HasMorePages = (!bUnprintable && (m_nStartRow > 0 && m_nStartRow < nNumItems) || m_nStartCol > 0);
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 < Columns.Count; i++)
{
ColumnHeader ch = Columns[i];
float fWidth = ch.Width / m_fDpi * 100 + 1; // Column width + separator
m_fListWidth += fWidth;
m_arColsWidth[i] = fWidth;
}
m_fListWidth += 1; // separator
}
}
}
Please visit: www.TyroDeveloper.com
Please Click on +1
Surprised nobody has said 'Thanks' so let me be the first to say a big thank you.
ReplyDeleteThank you kindly :)
ReplyDeleteSweet, thanks for sharing your effort.
ReplyDelete