Print RichTextBox text that is longer than one page? - c#

I've got the following code, and looked at as many similar questions on here and google, but all solutions have the same flaw, when the content in the RTB is longer than one page, or more than one or two lines, it prints an infinite number of pages. What should be changed to only print the correct number of pages?
private void PrintButton_Click(object sender, EventArgs e)
{
if (MainTabSet.TabCount > 0)
{
RichTextBox textbox = (RichTextBox)MainTabSet.SelectedTab.Controls["TabTextBox"];
PrintDocument docToPrint = new PrintDocument();
docToPrint.PrintPage += new PrintPageEventHandler(PrintPageHandler);
docToPrint.DocumentName = MainTabSet.SelectedTab.Text;
PrintDialog.Document = docToPrint;
if(PrintDialog.ShowDialog() == DialogResult.OK)
{
docToPrint.Print();
}
}
}
private void PrintPageHandler(object sender, PrintPageEventArgs e)
{
if (MainTabSet.TabCount > 0)
{
RichTextBox textbox = (RichTextBox)MainTabSet.SelectedTab.Controls["TabTextBox"];
StringReader reader = new StringReader(textbox.Text);
float linesPerPage = 0.0f;
float yPosition = 0.0f;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float rightMargin = e.MarginBounds.Right;
float topMargin = e.MarginBounds.Top;
string line = null;
Font printFont = textbox.Font; //maybe do selection font
SolidBrush printBrush = new SolidBrush(textbox.ForeColor);//Maybe do selection color
int charPos = 0;
int xPosition = (int)leftMargin;
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
while (count < linesPerPage && ((line = reader.ReadLine()) != null))
{
xPosition = (int)leftMargin;
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
count++;
for (int i = 0; i < line.Length; i++)
{
textbox.Select(charPos, 1);
if ((xPosition + ((int)e.Graphics.MeasureString(textbox.SelectedText, textbox.SelectionFont).Width)) > rightMargin)
{
count++;
if (!(count < linesPerPage))
{
break;
}
xPosition = (int)leftMargin;
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
}
printBrush = new SolidBrush(textbox.SelectionColor);
e.Graphics.DrawString(textbox.SelectedText, textbox.SelectionFont, printBrush, new PointF(xPosition, yPosition));
xPosition += ((int)e.Graphics.MeasureString(textbox.SelectedText, textbox.SelectionFont).Width);
charPos++;
}
}
if (line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
printBrush.Dispose();
}
}
}
Thanks in advance for the help.
//Nodnarb3

Add this code in PrintPageHandler
private void PrintPageHandler(object sender, PrintPageEventArgs e)
{
int charactersOnPage = 0;
int linesPerPage = 0;
// Sets the value of charactersOnPage to the number of characters
// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, font1,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);
// Draws the string within the bounds of the page
e.Graphics.DrawString(stringToPrint, font1, Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);
// Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage);
// Check to see if more pages are to be printed.
e.HasMorePages = (stringToPrint.Length > 0);
}
And the PrintButton Code
private void PrintButton_Click(object sender, EventArgs e)
{
stringToPrint = tabsProperties[tabsProperties.IndexOf(new TabProperties(this.tabControl1.SelectedIndex))].TabHtml;
printDialog1.ShowDialog();
printDocument1.Print();
}

Related

Print formatted Text with Images

I have been searching for long time to print formatted text and images which are in panel(PanelContain) but I have not get yet to print formatted text and images.Please tell me which text box support early I had used Rich text box but it does not convert in bitmap so I was getting blank text box.
Please help me.It is very very important for my project.
This is my code:
private void PrintPanel()
{
System.Drawing.Printing.PrintDocument doc = new PrintDocument();
doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
doc.Print();
}
private void doc_PrintPage(object sender, PrintPageEventArgs e)
{
try
{
RichTxtRptBody.BorderStyle = BorderStyle.None;
Bitmap bmp = new Bitmap(PanelContain.Width,
PanelContain.Height);
float tgtWidthMM = 210; //A4 paper size
float tgtHeightMM = 297;
float tgtWidthInches = tgtWidthMM / 25.4f;
float tgtHeightInches = tgtHeightMM / 25.4f;
float srcWidthPx = bmp.Width;
float srcHeightPx = bmp.Height;
float dpiX = srcWidthPx / tgtWidthInches;
float dpiY = srcHeightPx / tgtHeightInches;
bmp.SetResolution(dpiX, dpiY);
PanelContain.DrawToBitmap(bmp, PanelContain.ClientRectangle);
e.Graphics.InterpolationMode =
InterpolationMode.HighQualityBicubic;
e.Graphics.PageUnit = GraphicsUnit.Millimeter;
e.Graphics.DrawImage(bmp, 3, 1, tgtWidthMM, tgtHeightMM-24);
}
catch (Exception ex)
{
}
}
private void toolStripBtnPrint_Click(object sender, EventArgs e)
{
try
{
Img = null;
PrintDocument doc = new PrintDocument();
PrintDialog dlgSettings = new PrintDialog();
dlgSettings.Document = doc;
if (dlgSettings.ShowDialog() == DialogResult.OK)
{
PrintPanel();
}
}
catch (Exception ex)
{
}
}
I have also given a snapshot of my panel:
YOU can use webbrowsercontrol populate dynamically and then you can print easily as you want to print with full formatting option as html code can help you to give layout also.
You want to print a rich text box content with formatting
Try this :
Here eintragRichTextBox is a RichTextBox
private void druckenPictureBox_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
PrintDocument documentToPrint = new PrintDocument();
printDialog.Document = documentToPrint;
if (printDialog.ShowDialog() == DialogResult.OK)
{
StringReader reader = new StringReader(eintragRichTextBox.Text);
documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage);
documentToPrint.Print();
}
}
private void DocumentToPrint_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
StringReader reader = new StringReader(eintragRichTextBox.Text);
float LinesPerPage = 0;
float YPosition = 0;
int Count = 0;
float LeftMargin = e.MarginBounds.Left;
float TopMargin = e.MarginBounds.Top;
string Line = null;
Font PrintFont = this.eintragRichTextBox.Font;
SolidBrush PrintBrush = new SolidBrush(Color.Black);
LinesPerPage = e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics);
while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null))
{
YPosition = TopMargin + (Count * PrintFont.GetHeight(e.Graphics));
e.Graphics.DrawString(Line, PrintFont, PrintBrush, LeftMargin, YPosition, new StringFormat());
Count++;
}
if (Line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
PrintBrush.Dispose();
}

Print Preview shows "Document does not contain any pages" instead of the document

I am trying to set up an application in VS2013 with Page Setup, Print Preview and Print. The issue I am having is instead of seeing the page in the Print Preview window, all I see is "Document does not contain any pages." Everything I find on the Internet is regarding opening a file and printing/previewing it. I want to be able to print/preview unsaved text in a Rich Textbox.
Here is what I have:
PageSetupDialog psdlg = new PageSetupDialog();
PrintDialog pdlg = new PrintDialog();
PrintPreviewDialog ppdlg = new PrintPreviewDialog();
PrintDocument pd = new PrintDocument();
Event handlers:
private void pageSetupToolStripMenuItem_Click(object sender, EventArgs e)
{
psdlg.PrinterSettings = new System.Drawing.Printing.PrinterSettings();
psdlg.PageSettings = new System.Drawing.Printing.PageSettings();
psdlg.EnableMetric = false;
psdlg.ShowNetwork = true;
pd.PrinterSettings = psdlg.PrinterSettings;
psdlg.ShowDialog();
if (psdlg.PageSettings != null)
{
pd.DefaultPageSettings = psdlg.PageSettings;
}
}
private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
{
if (ppdlg.ShowDialog() == DialogResult.OK)
{
pd.DocumentName = strCurrentFile;
ppdlg.Document = pd;
}
}
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
if(printDialog1.ShowDialog() == DialogResult.OK)
{
pd.PrintPage += new PrintPageEventHandler (pd_PrintPage);
pd.Print();
}
}
PrintPage Event Handler:
private void DocumentToPrint_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
StringReader reader = new StringReader(rtbMain.Text);
float LinesPerPage = 0;
float YPosition = 0;
int Count = 0;
float LeftMargin = e.MarginBounds.Left;
float TopMargin = e.MarginBounds.Top;
string Line = null;
Font PrintFont = this.rtbMain.Font;
SolidBrush PrintBrush = new SolidBrush(Color.Black);
LinesPerPage = e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics);
while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null))
{
YPosition = TopMargin + (Count * PrintFont.GetHeight(e.Graphics));
e.Graphics.DrawString(Line, PrintFont, PrintBrush, LeftMargin, YPosition, new StringFormat());
Count++;
}
if (Line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
PrintBrush.Dispose();
}

C # Code to Print String in Pre Formated Style

I Have written this code to formats textbox
for (int i = 0; i < datGrid.Rows.Count - 1; i++)
{
String data = String.Format(
"{0,-18} {1,-10} {2,-10} {3,-7} {4,-10} | {5,5} ",
datGrid.Rows[i].Cells[0].Value.ToString(),
datGrid.Rows[i].Cells[1].Value.ToString(),
datGrid.Rows[i].Cells[2].Value.ToString(),
datGrid.Rows[i].Cells[3].Value.ToString(),
datGrid.Rows[i].Cells[4].Value.ToString(),
datGrid.Rows[i].Cells[5].Value.ToString());
textBox1.Text += "\n" + data;
data = "";
}
textBox1.Text += "\n------------------------------------";
textBox1.Text += "\n" +
String.Format("{0,-1}{1,-10}{2,-2}{3,-10}{4,-2}{5,-1}",
"Total :" + " ", labelTotal.Text+" ",
"Paid :" + " ", labelPaid.Text + " ",
"Balance:" + " ", labelBalance.Text);
I Used followiing code to print
streamToPrint = new StringReader(textBox1.Text);
streamToPrint.InitializeLifetimeService();
try
{
printFont = new Font("Arial", 8);
dialog.Document = pd;
PaperSize paperSize = new PaperSize("My Envelope",410,420);
pd.DefaultPageSettings.PaperSize = paperSize;
// pd.DefaultPageSettings.Landscape = true;
pd.DefaultPageSettings.Margins = new Margins(5, 5,5, 10);
pd.PrintPage += new PrintPageEventHandler (this.pd_PrintPage);
if (dialog.ShowDialog() == DialogResult.OK)
{
pd.Print();
}
}
finally
{
streamToPrint.Close();
}
And to print text following code
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 < linesPerPage &&
((line = streamToPrint.ReadLine()) != null))
{
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin - 3,
yPos - 5, new StringFormat(StringFormatFlags.LineLimit));
count++;
}
// If more lines exist, print another page.
if (line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
//ev.Graphics.DrawString(textBox1.Text,
// new Font("Arial", 20, FontStyle.Regular), Brushes.Black, 20,20);
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
But I want to print in tabular format that I have given. This code is not working.
Your printFont is a proportional font (Arial) and therefore will not work with your type of tabular formatting. You have two options:
Pick a fixed size font like Consolas. This will fix the problem without hassle.
Print those chunks you feed into your formatted string separately to their respective horizontal positions. This allows you to use any Font you like.
BTW: You write that you put the same text into a TextBox. It should have the same problems, but only the first option will work there without being a pain..!

printing a note pad text file

i am trying to print this document but only gives me a blank page.
i have checked the Password.txt File is not empty so i dont know why its printing out a blank page . this is C# coding
private void button6_Click(object sender, EventArgs e)
{
StreamReader Printfile = new StreamReader("c:\\testDir1\\Password.txt);
try
{
PrintDocument docToPrint = new PrintDocument();
docToPrint.DocumentName = "Password";
printDialog1.AllowSomePages = true;
printDialog1.ShowHelp = true;
printDialog1.Document = docToPrint;
DialogResult result = printDialog1.ShowDialog();
printPreviewDialog1.Document = docToPrint;
printPreviewDialog1.ShowDialog();
Printfile.Close();
if (result == DialogResult.OK)
{
docToPrint.Print();
MessageBox.Show("Printing file");
}
}
catch (System.Exception f)
{
MessageBox.Show(f.Message);
}
finally
{
Printfile.Close();
}
}
The PritnDocument will fire the PrintPage event for every page that needs to be printed. You can hook into that event and "Draw" your page. In your case, draw a string for every line in the text file.
Font printFont = new Font("Arial", 10);
StreamReader Printfile;
private void button6_Click(object sender, EventArgs e)
{
using(StreamReader Printfile = new StreamReader("c:\\testDir1\\Password.txt")) //file path
{
try
{
PrintDocument docToPrint = new PrintDocument();
docToPrint.DocumentName = "Password"; //Name that appears in the printer queue
docToPrint.PrintPage += (s, 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 < linesPerPage && ((line = Printfile.ReadLine()) != null))
{
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, new StringFormat());
count++;
}
// If more lines exist, print another page.
if (line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
};
docToPrint.Print();
}
catch (System.Exception f)
{
MessageBox.Show(f.Message);
}
}
}

c# - print RichTextBox text with correct spacing

I am making a program that can write in Bengali (a virtual keyboard) or in English. Everything was perfect until I started programming the printing. The user should be able to select any text and change the font and color. Because every character could be different, I need to print character by character. Here is my code:
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
PrintDialog print = new PrintDialog();
doc = new System.Drawing.Printing.PrintDocument();
print.Document = doc;
doc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDoc);
if (print.ShowDialog() == DialogResult.OK)
{
doc.Print();
}
}
private void printDoc(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
System.IO.StringReader reader = new System.IO.StringReader(richTextBox1.Text);
float linesPerPage = 0;
float yPosition = 0;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float rightMargin = e.MarginBounds.Right;
float topMargin = e.MarginBounds.Top;
string line = null;
Font printFont = this.richTextBox1.Font;
SolidBrush printBrush = new SolidBrush(Color.Black);
int charpos = 0;
int xPosition = (int)leftMargin;
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
while (count < linesPerPage && ((line = reader.ReadLine()) != null))
{
xPosition = (int)leftMargin;
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
count++;
for (int i = 0; i < line.Length; i++)
{
richTextBox1.Select(charpos, 1);
if ((xPosition + ((int)e.Graphics.MeasureString(richTextBox1.SelectedText, richTextBox1.SelectionFont).Width)) > rightMargin)
{
count++;
if (!(count < linesPerPage))
{
break;
}
xPosition = (int)leftMargin;
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
}
printBrush = new SolidBrush(richTextBox1.SelectionColor);
e.Graphics.DrawString(richTextBox1.SelectedText, richTextBox1.SelectionFont, printBrush, new PointF(xPosition, yPosition));
xPosition += ((int)e.Graphics.MeasureString(richTextBox1.SelectedText, richTextBox1.SelectionFont).Width);
charpos++;
}
}
if (line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
printBrush.Dispose();
}
}
However, when I get a print preview, it shows a space between each of the the characters:
I think this is because e.Graphics.MeasureString() is not giving me the tightest bounding box possible, or it's not giving me the exact width of the character as specified by the font. I'm quite new to C# Anyone know of a way to get the exact width of a character? It's been stumping me for a long time.
According to this MSDN article:
The (Graphics Class) MeasureString method is designed for use with individual string and includes a small amount of extra space before and after the string to allow for overhanging glyphs
You can instead use TextRenderer.MeasureString() to get the precise font width.
GOT IT. Finally. You need to use e.Graphics.MeasureString() after all. Just another overload of it. Use this:
e.Graphics.MeasureString(richTextBox1.SelectedText, richTextBox1.SelectionFont, new PointF(xPosition, yPosition), StringFormat.GenericTypographic).Width;
To remove the space you need to pass StringFormat.GenericTypographic. Hope it helps. (you can use my code for printing text with different color and text if you replace e.Graphics.MeasureString(string, Font) with the above).

Categories

Resources