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..!
Related
I want this to take a given piece of text and display it as a paragraph correctly (jumping to new line when needed) using DrawString and for(;;) loop, but the result is bonkers.
private void pnlText_Paint(object sender, PaintEventArgs e)
{
pnlText.Font = new Font("Calibri", 14, FontStyle.Regular);
SizeF lineSize = new SizeF();
for (int i = 0; i < DisplayText.Length; i++)
{
currentLine += DisplayText[i];
lineSize = e.Graphics.MeasureString(currentLine, pnlText.Font);
if (DisplayText[i].ToString() == " " && lineSize.Width >= 820)
{
paragraph += currentLine + "\n";
currentLine = null;
}
}
using (SolidBrush br = new SolidBrush(Color.Black))
{
e.Graphics.DrawString(paragraph, pnlText.Font, br, 5, 5);
}
}
The output:
one sentence whole paragraph
I am dumbstruck, it makes no sense for it to repeat like that.
I have tried using String Builder and replacing DisplayText.Length with a number and it still doesn't work right. Using foreach and drawing each char seperately works, albeit messes up spacing.
Also initially I didn't have "paragraph" string and I simply drew each line inside the loop, but that somehow caused the end of the text to be cut off and pasted at the very beginning which is even more insane. I am getting suspicious my computer is possessed with deamons.
It seems that your paragraph variable has a shared state. Verify you reset the state for each button click like that:
private void pnlText_Paint(object sender, PaintEventArgs e)
{
pnlText.Font = new Font("Calibri", 14, FontStyle.Regular);
SizeF lineSize = new SizeF();
paragraph = ""; // that should reset the paragraph variable between invocations
for (int i = 0; i < DisplayText.Length; i++)
{
currentLine += DisplayText[i];
lineSize = e.Graphics.MeasureString(currentLine, pnlText.Font);
if (DisplayText[i].ToString() == " " && lineSize.Width >= 820)
{
paragraph += currentLine + "\n";
currentLine = null;
}
}
using (SolidBrush br = new SolidBrush(Color.Black))
{
e.Graphics.DrawString(paragraph, pnlText.Font, br, 5, 5);
}
}
Or simply define it inside the pnlText_Paint method
Hope it helps :)
private void pnlText_Paint(object sender, PaintEventArgs e)
{
pnlText.Font = new Font("Calibri", 14, FontStyle.Regular);
SizeF lineSize = new SizeF();
currentLine = null;
paragraph = null;
for (int i = 0; i < DisplayText.Length; i++)
{
currentLine += DisplayText[i];
lineSize = e.Graphics.MeasureString(currentLine, pnlText.Font);
if (DisplayText[i].ToString() == " " && lineSize.Width >= 820)
{
paragraph += currentLine + "\n";
currentLine = null;
}
}
paragraph += currentLine;
using (SolidBrush br = new SolidBrush(Color.Black))
{
e.Graphics.DrawString(paragraph, pnlText.Font, br, 5, 5);
}
}
Followed Hans Kesting advice and now it works. Something is calling the paint event more than once, hence the strings are not null to begin with.
I have the following issue when trying to draw a string and then printing it to PDF by Amyuni Printer :
where I couldn't select the text when pressing (Ctrl+A) , I need this PDF file to use it into another PDF reader , and it seems that the reader , tries to read the selected area not the actual text area .
I'm using the following code to do this stuff :
Font printFont = new Font("Simplified Arabic Fixed", (float)11, FontStyle.Regular);
StreamReader Printfile;
using (StreamReader Printfile = new StreamReader(#"C:\20_2.txt", Encoding.Default))
{
try
{
PrintDocument docToPrint = new PrintDocument();
PaperSize ps = new PaperSize("A4", 827, 1169);
bool bolFirstPage = true;
docToPrint.DefaultPageSettings.PaperSize = ps;
docToPrint.DefaultPageSettings.Landscape = true;
docToPrint.DocumentName = "docName" + DateTime.Now.Ticks.ToString(); //Name that appears in the printer queue
string FirstLine = Printfile.ReadLine();
bool bIsArabic = true;
docToPrint.PrintPage += (s, ev) =>
{
float nFontHight = printFont.GetHeight(ev.Graphics);
bIsArabic = true;
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = 1008;
float topMargin = 120;
string line = null;
//Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics) + 2;
Image img = Image.FromFile(#"C:\image.bmp");
ev.Graphics.DrawImage(img, 6, 1, 1095, 728);
//***Image Reslution is Working good -->***
StringFormat format = new StringFormat()/*arabic*/;
line = Printfile.ReadLine();
format = new StringFormat(StringFormatFlags.DisplayFormatControl | StringFormatFlags.DirectionRightToLeft)/*arabic*/;
do
{
yPos = topMargin + ((count) * printFont.GetHeight(ev.Graphics) * (float)0.91);
line = " تجربة تجربة تجربة تجربة تجربة";
ev.Graphics.DrawString(line, printFont, Brushes.DeepPink, leftMargin, yPos, format);
count++;
} while ((line = Printfile.ReadLine()) != null && !line.Contains(''));// lines contains \0 as UniCode
// 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);
}
}
}
when I'm using another font type like "Arial" I can select near to 90% of the text, but unfortunately I have to use only the font type "Simplified Arabic Fixed" , and I'm using windows server 2003.
one more thing , when i try to print directly Arabic text from notepad it's work fine.
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();
}
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);
}
}
}
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).