CSharp/C# >> Print Documents PrintDocument-- (PrintDocument is much harder than it looks)

by raylopez99 » Fri, 29 Aug 2008 18:06:52 GMT

Spoke too soon! I tried printing more than two pages, and found that
the code is truncated after two pages. So my optimism was premature.

Now I'm stuck again...how to make this code work for printing more
than two pages of text?

If you have a sample print method you can upload for future reference
I would be greatful.

Tx,

RL

raylopez99 wrote:
>
> Now the code works flawlessly.
>

CSharp/C# >> Print Documents PrintDocument-- (PrintDocument is much harder than it looks)

by Family Tree Mike » Sat, 30 Aug 2008 07:29:56 GMT


These controls would be on the form: FileLabel, ChooseFileButton,
PrintFileButton, QuitButton, and ContentsTextBox. The control types are
hopefully obvious...

This is quick code, and I know one issue is the text lines are not checked
if they go off the right side of the page. You will note that I am working
with the text lines, not the contents of the text box.

Hopefully this is helpfull to you or others....

Mike

================================================

public partial class MyPrintAppUI : Form
{
private string TextFileName { get; set; }
private string[] TextLines { get; set; }

public MyPrintAppUI()
{
InitializeComponent();

TextFileName = "Unknown.txt";
FileLabel.Text = TextFileName;

ChooseFileButton.Click += new EventHandler(ChooseFileButton_Click);
PrintFileButton.Click += new EventHandler(PrintFileButton_Click);
QuitButton.Click += delegate { Close(); };
}

private void ChooseFileButton_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
TextFileName = ofd.FileName;
FileLabel.Text = TextFileName;
TextLines = File.ReadAllLines(TextFileName);
ContentsTextBox.Text = File.ReadAllText(TextFileName);
}
}
}

private void PrintFileButton_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
pd.Print();
}

private int LineIndex = 0;

private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
int LinesPerPage = 0, y = 0, count = 0;
int LeftMargin = e.MarginBounds.Left;
int TopMargin = e.MarginBounds.Top;

using (Font printFont = new Font("Arial", 10))
{
LinesPerPage = (int)(e.MarginBounds.Height /
printFont.GetHeight(e.Graphics));
while ((count < LinesPerPage) && (LineIndex < TextLines.Length))
{
y = (int) (TopMargin + (count * printFont.GetHeight(e.Graphics)));
e.Graphics.DrawString(TextLines[LineIndex], printFont, Brushes.Black,
LeftMargin, y, new StringFormat());
++count;
++LineIndex;
}
}

e.HasMorePages = LineIndex < TextLines.Length;
}
}




================================================

CSharp/C# >> Print Documents PrintDocument-- (PrintDocument is much harder than it looks)

by raylopez99 » Sat, 30 Aug 2008 19:16:05 GMT

On Aug 29, 4:29爌m, "Family Tree Mike"




Thanks FTM. I will go over this code and if I have any questions or
improvements will post back. I notice though it does have a way of
breaking out of the loop by counting lines and text length that seems
more robust than the web example I originally posted and modified, so
hopefully I'll get this to work.

RL

CSharp/C# >> Print Documents PrintDocument-- (PrintDocument is much harder than it looks)

by raylopez99 » Sun, 31 Aug 2008 00:25:42 GMT

ere is the complete, updated program, and it works fine, including
the margins. Don't forget to set your textbox "MaxLength" property
(found in the Designer Wizard properties tab) to something bigger than
the default 32k if you intend to print lots of pages).

The important change was here: textBox1.Text = mylocalstring; //works
now, problem solved

Making this one line change enabled the program to avoid printing an
infinite loop.

This code adapted from these two sources (mainly the first source,
which had the small bug I mention above, and did not quite work):

//adapted from http://www.expresscomputeronline.com/20030915/techspace02.shtml
//main code from here // an excellent example, too bad it doesn't work
for me the first time (without the changes made now--now it works)
// and from Chris Sells, Chapter 8, Printing in WinForms
//Chris Sells Chap 8 is very very simplistic--in retrospect I suspect
because printing is difficult and he didn't want to spend time on it

//SOF
using System;
using System.Collections.Generic;
using System.ComponentModel; //I don't think you need some of these
using directives, but I think you need .Printing for sure
using System.Data;
using System.Drawing;
using System.Linq; //not needed in this example
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing.Printing;


namespace MyNameSpace01
{
public partial class MyFormTextBox : Form
{
string myPrintFilename;
StringBuilder myGlobalString;
Font f;
SolidBrush b;
StringFormat strformat;
string printstr;
int Char_out_, Lines_out;
bool DirtyBool_not_used;
bool bool_YorN_Printed;

// StreamReader reader;


public MyFormTextBox()
{
InitializeComponent();
myGlobalString = new StringBuilder("");
strformat = new StringFormat();
DirtyBool_not_used = true;
bool_YorN_Printed = false;

}


private void myPrintButton_Click(object sender, EventArgs e)
{
if (myPrintFilename != "")
{
DirtyBool_not_used = false;
bool_YorN_Printed = false;
int length_myTextBox = myTextBox.Text.Length;
myGlobalString = new StringBuilder(length_myTextBox +
1);

myGlobalString.Append(myTextBox.Text); ////*&%
this.printDocument1.DocumentName =
this.myPrintFilename;

this.printDocument1.Print();
}
else
{
DirtyBool_not_used = true;
}

}

private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{


RectangleF myrect = new
RectangleF(e.MarginBounds.Left,e.MarginBounds.Top,
e.MarginBounds.Width,e.MarginBounds.Height);
SizeF sz = new SizeF(e.MarginBounds.Width,
e.MarginBounds.Height);

string string_temp = myTextBox.Text;

string mylocalstring = myTextBox.Text; //also equivalent
it turns out--same thing!//works


e.Graphics.MeasureString(mylocalstring, f, sz, strformat,
out Char_out_, out Lines_out);

printstr = mylocalstring.Substring(0,Char_out_);
// myTextBox.Text = printstr; //only prints two pages-error

CSharp/C# >> Print Documents PrintDocument-- (PrintDocument is much harder than it looks)

by raylopez99 » Sun, 31 Aug 2008 01:16:34 GMT


Minor 'bug' fix of sorts: replace - sb.Append(s);

with:

sb.AppendLine(s);

if you want line breaks preserved in any text you import from a file.

RL

Similar Threads

1. Have C# PrintDocument and VC++6 DLL printing on the same print job - CSharp/C#

2. Print pdf document using PRintDocument

Hi,
Can we print a pdf document using .Net PrintDocument class? If yes then how? 
I dont wanna use Win32 spooler functions as it require all that DLLIMports 
etc.

Thanks

3. Printing to a Word document using PrintDocument class - VB.Net

4. Print Documents PrintDocument-- what am I doing wrong? Must be something stupid

I am running out of printing paper trying to debug this...it has to be
trivial, but I cannot figure it out--can you?  Why am I not printing
text, but just the initial string "howdy"?

On the screen, when I open a file, the entire contents of the file is
in fact being shown...so why can't I print it later?  All of this code
I am getting from a book (Chris Sells) and the net.  The solution is
to be found in the fact that stringbuilder is not retaining
information outside the 'using' bracket, despite the fact I made it
'global'.

Keyword search //!!! below to see where I think the problem lies.

RL

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


namespace MyNameSpace1
{
    public partial class MyForm : Form
    {
        string myPrintFilename;
        StringBuilder myGlobalStringBuilder;  //!!! this is supposed
to be global to the form MyForm, right?

        string strModified; // = String.Copy(strOriginal); //not used

        public MyForm()
        {
            InitializeComponent();
            myGlobalStringBuilder = new StringBuilder("howdy"); //!!!
the only thing that gets printed is 'howdy'!

        }

        private void toolStripButton1_Click(object sender, EventArgs
e)
        {
            Stream myStream;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Title = "Open text file";
            openFileDialog1.InitialDirectory = @"c:\";
            openFileDialog1.Filter = "txt files (*.txt)|*.txt|All
files (*.*)|*.*";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    if ((myStream = openFileDialog1.OpenFile()) !=
null)
                    {
                        using (myStream)
                        {
                            StreamReader sr =
File.OpenText(openFileDialog1.FileName);
                            string s = sr.ReadLine();
                            StringBuilder sb = new StringBuilder();
                            while (s != null)
                            {
                                sb.Append(s);
                                s = sr.ReadLine();
 
myGlobalStringBuilder.Append(s); //!!! ???  Why is myGlobal not
appending here?
                            }
                            sr.Close();
                            textBox1.Text = sb.ToString(); //this
works, to show the file text on the screen textBox1

                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: could not read file from
disk (myStream); Err: " + ex.Message);
                }
            }
        }

        private void printToolStripButton_Click(object sender,
EventArgs e)
        {
            if (myPrintFilename != "")
            {
                this.printDocument1.DocumentName =
this.myPrintFilename;

            this.printDocument1.Print();
            }
        }

        private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
        {
            //p. 292 Chris Sells
            //draw to the e.Graphics object that wraps the print
target

            Graphics g = e.Graphics;
            using (Font font = new Font("Lucida Console", 48) )
            {
                string mylocalstring;

                mylocalstring =
myGlobalStringBuilder.ToString(); //!!! only prints "Howdy"--the
initial string--never the appended string from myGlobalStringBuilder--
why?

                if (myGlobalStringBuilder.Length != 0)
                {
                    g.DrawString(mylocalstring, font, Brushes.Blue, 0,
0);
                }
            }

           }


    }
}



5. Print Documents PrintDocument-- what am I doing wrong? Must be so - CSharp/C#

6. Print Documents PrintDocument-- what am I doing wrong? Must be so

Set a breakpoint in printDocument1_PrintPage, at the line where 
"mylocalstring" is set.  I believe you will see that the value is correct for 
"myStringBuilder".  The lack of carriage returns will hide the fact that the 
string is correct when printed.  I believe it is going off the page.  The 
print document functions won't fix newlines, wrapping, etc.  Also, you need 
to worry about the next page when the text is long.  Printing is very 
complicated in .net, until you get the hang of it...

"raylopez99" wrote:

> I am running out of printing paper trying to debug this...it has to be
> trivial, but I cannot figure it out--can you?  Why am I not printing
> text, but just the initial string "howdy"?
> 
> On the screen, when I open a file, the entire contents of the file is
> in fact being shown...so why can't I print it later?  All of this code
> I am getting from a book (Chris Sells) and the net.  The solution is
> to be found in the fact that stringbuilder is not retaining
> information outside the 'using' bracket, despite the fact I made it
> 'global'.
> 
> Keyword search //!!! below to see where I think the problem lies.
> 
> RL
> 
> using System;
> using System.Collections.Generic;
> using System.ComponentModel;
> using System.Data;
> using System.Drawing;
> using System.Linq;
> using System.Text;
> using System.IO;
> using System.Windows.Forms;
> using System.Diagnostics;
> 
> 
> namespace MyNameSpace1
> {
>     public partial class MyForm : Form
>     {
>         string myPrintFilename;
>         StringBuilder myGlobalStringBuilder;  //!!! this is supposed
> to be global to the form MyForm, right?
> 
>         string strModified; // = String.Copy(strOriginal); //not used
> 
>         public MyForm()
>         {
>             InitializeComponent();
>             myGlobalStringBuilder = new StringBuilder("howdy"); //!!!
> the only thing that gets printed is 'howdy'!
> 
>         }
> 
>         private void toolStripButton1_Click(object sender, EventArgs
> e)
>         {
>             Stream myStream;
>             OpenFileDialog openFileDialog1 = new OpenFileDialog();
>             openFileDialog1.Title = "Open text file";
>             openFileDialog1.InitialDirectory = @"c:\";
>             openFileDialog1.Filter = "txt files (*.txt)|*.txt|All
> files (*.*)|*.*";
> 
>             if (openFileDialog1.ShowDialog() == DialogResult.OK)
>             {
>                 try
>                 {
>                     if ((myStream = openFileDialog1.OpenFile()) !=
> null)
>                     {
>                         using (myStream)
>                         {
>                             StreamReader sr =
> File.OpenText(openFileDialog1.FileName);
>                             string s = sr.ReadLine();
>                             StringBuilder sb = new StringBuilder();
>                             while (s != null)
>                             {
>                                 sb.Append(s);
>                                 s = sr.ReadLine();
>  
> myGlobalStringBuilder.Append(s); //!!! ???  Why is myGlobal not
> appending here?
>                             }
>                             sr.Close();
>                             textBox1.Text = sb.ToString(); //this
> works, to show the file text on the screen textBox1
> 
>                         }
>                     }
>                 }
>                 catch (Exception ex)
>                 {
>                     MessageBox.Show("Error: could not read file from
> disk (myStream); Err: " + ex.Message);
>                 }
>             }
>         }
> 
>         private void printToolStripButton_Click(object sender,
> EventArgs e)
>         {
>             if (myPrintFilename != "")
>             {
>                 this.printDocument1.DocumentName =
> this.myPrintFilename;
> 
>             this.printDocument1.Print();
>             }
>         }
> 
>         private void printDocument1_PrintPage(object sender,
> System.Drawing.Printing.PrintPageEventArgs e)
>         {
>             //p. 292 Chris Sells
>             //draw to the e.Graphics object that wraps the print
> target
> 
>             Graphics g = e.Graphics;
>             using (Font font = new Font("Lucida Console", 48) )
>             {
>                 string mylocalstring;
> 
>                 mylocalstring =
> myGlobalStringBuilder.ToString(); //!!! only prints "Howdy"--the
> initial string--never the appended string from myGlobalStringBuilder--
> why?
> 
>                 if (myGlobalStringBuilder.Length != 0)
>                 {
>                     g.DrawString(mylocalstring, font, Brushes.Blue, 0,
> 0);
>                 }
>             }
> 
>            }
> 
> 
>     }
> }
> 
> 
> 
> 

7. Print Documents PrintDocument-- what am I doing wrong? Must be something stupid - CSharp/C#

8. Can I monitor PrintDocument.Print?

I want to do something like this to interrupt the print process (But
this does not work because the error is "cannot implicitly conver type
void to bool"):

while(pd.Print())
{
pCounter++;

if(printerSettings.Copies == 2)
{
pd.DefaultPageSettings.PaperSource =
pd.PrinterSettings.PaperSources[comboBox1.SelectedIndex = 5];

}
if(printerSettings.Copies == 1)
{
pd.DefaultPageSettings.PaperSource =
pd.PrinterSettings.PaperSources[comboBox1.SelectedIndex = 6];

}
if(pCounter == 6)
								break;

						}
Thanks,
Trint