Wednesday, February 18, 2009

Printing in C# (2)

Printing in C#, an Introduction Which Works


Printing, previewing, and setting up pages is not simple. Here's an attempt at getting a
novice started. It's my second attempt (and I hope my last); the first attempt is also shown on this blog.


Starting out with a new Project (named PrintTest2 here), in the Form editor, we drag from the toolbar the buttons and Printing components we need.

The final form at the end of the insertion process has three buttons, and four non-Form related items (they are below the form). As usual, their names, the identifiers used to address them, can be changed.


I'm assuming that the reader will also borrow code as necessary. The only thing different here is that instead of having a fixed text file for viewing or printing, I've put in an OpenFile dialog which is off topic). Of course, I could have put in two, one for printing and one for previewing, but the reader can easily do this if s/he wishes, which shows (4 components added from the toolbox.

The code has been copied from MSDN (I think there's automatically permission given to this kind of non-profit quoting) in large measure. Here's the full code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.IO;


namespace PrintTest2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void pageSetupButton_Click(object sender, EventArgs e)
//This method displays a PageSetupDialog object. If the
// user clicks OK in the dialog, selected results of
// the dialog are displayed in ListBox1.
{

// Initialize the dialog's PrinterSettings property to hold user
// defined printer settings.
PageSetupDialog1.PageSettings =
new System.Drawing.Printing.PageSettings();

// Initialize dialog's PrinterSettings property to hold user
// set printer settings.
PageSetupDialog1.PrinterSettings =
new System.Drawing.Printing.PrinterSettings();

//Do not show the network in the printer dialog.
PageSetupDialog1.ShowNetwork = false;

//Show the dialog storing the result.
DialogResult result = PageSetupDialog1.ShowDialog();

// If the result is OK, display selected settings in
// ListBox1. These values can be used when printing the
// document.
if (result == DialogResult.OK)
{
object[] results = new object[]{
PageSetupDialog1.PageSettings.Margins,
PageSetupDialog1.PageSettings.PaperSize,
PageSetupDialog1.PageSettings.Landscape,
PageSetupDialog1.PrinterSettings.PrinterName,
PageSetupDialog1.PrinterSettings.PrintRange};
//listBox1.Items.AddRange(results);//changed case (l)istBox1
}
}


// The Click event is raised when the user clicks the Print button.
private void printButton_Click_1(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "txt files (*.txt)*.txtAll files (*.*)*.*";
dialog.InitialDirectory = "C:\\";
dialog.Title = "Choose a file to print";
if (dialog.ShowDialog() == DialogResult.OK)
{

PrintDocument pd = new PrintDocument();
PrintDialog dlgSettings = new PrintDialog();

dlgSettings.Document = pd;
pd.DocumentName = dialog.FileName;
if (dlgSettings.ShowDialog() == DialogResult.OK)

{
try
{
streamToPrint = new StreamReader
(dialog.FileName);
try
{
printFont = new Font("Arial", 10);

pd.PrintPage += new PrintPageEventHandler
(this.pd_PrintPage);
pd.Print();
}
finally
{
streamToPrint.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}

// The PrintPage event is raised for each page to be printed.
private void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
string line = null;

// Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height /
printFont.GetHeight(ev.Graphics);

// Print each line of the file.
while (count < line =" streamToPrint.ReadLine())" ypos =" topMargin" hasmorepages =" true;" hasmorepages =" false;" document =" printDocument1;" printpreviewdialog1 =" new" printdocument1 =" new" printpreviewdialog1 =" new" clientsize =" new" location =" new" name = "PrintPreviewDialog2" minimumsize =" new" useantialias =" true;" charactersonpage =" 0;" linesperpage =" 0;" stringtoprint =" stringToPrint.Substring(charactersOnPage);" hasmorepages =" (stringToPrint.Length"> 0);

// If there are no more pages, reset the string to be printed.
if (!e.HasMorePages)
stringToPrint = documentContents;
}

private void ReadDocument()//used in preview
{
string docName = "isorecorder.log";
string docPath = @"c:\";
printDocument1.DocumentName = docName;
using (FileStream stream = new FileStream(docPath + docName, FileMode.Open))
using (StreamReader reader = new StreamReader(stream))
{
documentContents = reader.ReadToEnd();
}
stringToPrint = documentContents;
}


private Font printFont;
private StreamReader streamToPrint;
// the following is from http://msdn.microsoft.com/en-us/library/ms404294(printer).aspx

// Declare a string to hold the entire document contents.
private string documentContents;

// Declare a variable to hold the portion of the document that
// is not printed.
private string stringToPrint;
}
}

Here is the InitializeComponent() code generated during the dragging operations:


namespace PrintTest2
{
partial class Form1
{
///


/// Required designer variable.
///

private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///

/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.printButton = new System.Windows.Forms.Button();
this.printDocument1 = new System.Drawing.Printing.PrintDocument();
this.printDialog1 = new System.Windows.Forms.PrintDialog();
this.PageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
this.previewButton = new System.Windows.Forms.Button();
this.pageSetupButton = new System.Windows.Forms.Button();
this.printPreviewDialog1 = new System.Windows.Forms.PrintPreviewDialog();
this.SuspendLayout();
//
// printButton
//
this.printButton.Location = new System.Drawing.Point(12, 12);
this.printButton.Name = "printButton";
this.printButton.Size = new System.Drawing.Size(125, 23);
this.printButton.TabIndex = 0;
this.printButton.Text = "Press to Print";
this.printButton.UseVisualStyleBackColor = true;
this.printButton.Click += new System.EventHandler(this.printButton_Click_1);
//
// printDocument1
//
this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);
//
// printDialog1
//
this.printDialog1.UseEXDialog = true;
//
// previewButton
//
this.previewButton.Location = new System.Drawing.Point(162, 12);
this.previewButton.Name = "previewButton";
this.previewButton.Size = new System.Drawing.Size(125, 23);
this.previewButton.TabIndex = 2;
this.previewButton.Text = "Press to Preview";
this.previewButton.UseVisualStyleBackColor = true;
this.previewButton.Click += new System.EventHandler(this.previewButton_Click);
//
// pageSetupButton
//
this.pageSetupButton.Location = new System.Drawing.Point(302, 12);
this.pageSetupButton.Name = "pageSetupButton";
this.pageSetupButton.Size = new System.Drawing.Size(125, 23);
this.pageSetupButton.TabIndex = 3;
this.pageSetupButton.Text = "Press to SetUp Page";
this.pageSetupButton.UseVisualStyleBackColor = true;
this.pageSetupButton.Click += new System.EventHandler(this.pageSetupButton_Click);
//
// printPreviewDialog1
//
this.printPreviewDialog1.AutoScrollMargin = new System.Drawing.Size(0, 0);
this.printPreviewDialog1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
this.printPreviewDialog1.ClientSize = new System.Drawing.Size(400, 300);
this.printPreviewDialog1.Enabled = true;
this.printPreviewDialog1.Icon = ((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon")));
this.printPreviewDialog1.Name = "PrintPreviewDialog1";
this.printPreviewDialog1.Visible = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(438, 59);
this.Controls.Add(this.pageSetupButton);
this.Controls.Add(this.previewButton);
this.Controls.Add(this.printButton);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button printButton;
private System.Windows.Forms.PrintDialog printDialog1;
private System.Windows.Forms.PageSetupDialog PageSetupDialog1;
private System.Windows.Forms.Button previewButton;
private System.Windows.Forms.Button pageSetupButton;
public string documentsContents;
}
}

I find all of this incomprehensible in the sense that dragging the printing parts to the form was treated so differently, and non-intuitively, from dragging buttons, labels, etc..Debugging it was just plain terrible. But it works, and as of II/2009, please accept it as useful.

2 comments:

  1. Hi...
    I wonder why i haven't found this site before. Actually, i am learning C# since one month and always try to gain more practice knowledge. Thank you so posting such an important and simple to understand coding here.

    ReplyDelete
  2. hi.... can i have the code for printing a table from database. the language i used is c#.net. now a days im doing my finel semester project.

    ReplyDelete