I have a listbox with 1 or more textfiles, which im going to print as commands.
but I dont know how to make the streamreader read from listbox ?
so far I got this.:
public void OutputBtn_Click(object sender, EventArgs e)
{
PrintDocument PrintD = new PrintDocument();
PrintD.PrintPage += new PrintPageEventHandler(this.PrintDocument_PrintPage);
StreamReader SR = new StreamReader("C:\\myfile.txt");
PrintD.Print();
}
is there enyway I can change "C:\myfile.txt" or do I have to use "foreach" ?
Do you want something like this? I don't fully understand the question
string[] fileEntries = Directory.GetFiles("C:\\temp\\").Where(p =>
p.EndsWith(".txt")).ToArray<string>();
foreach (string fileName in fileEntries)
{
lb.Items.Add(new ListItem(fileName, fileName);
}
Ok so you have the listbox filled with filenames?
private StreamReader sr;
public void OutputBtn_Click(object sender, EventArgs e)
{
foreach(var li in lb.Items)
{
PrintDocument PrintD = new PrintDocument();
PrintD.PrintPage += new PrintPageEventHandler(this.PrintDocument_PrintPage);
sr = new StreamReader(li.ToString());
PrintD.Print();
}
}
private void PrintDocument_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) ;
// Iterate over the file, printing each line.
while (count < linesPerPage && ((line = sr.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;
}
Related
I generate several QRCodes and would like to print the barcodes one after another on an A4 size page in Print Preview Control. I also use this control: PrintBar
I calculated, that about 5 QRCodes can be on an A4 format page, so I tried to split with HasMorePages.
Print Preview without HasMorePages: the A4 page with the QRCodes screenshot - the last QRCode should be on the last page.
I added e.HasMorePages and return, but is not working correctly...It counts the pages to infinite and after that crashes.
My code:
BeginPrint
private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
this.currentItem = 0;
}
PrintPage
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
String fontName = "Arial";
Font fontNormal = new Font(fontName, 12, System.Drawing.FontStyle.Regular);
float itemHeight = fontNormal.GetHeight(e.Graphics);
Brush normalColour = Brushes.Black;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
float printWidth = e.MarginBounds.Width;
float printHeight = e.MarginBounds.Height;
float rightMargin = leftMargin + printWidth;
float currentPosition = topMargin;
float numberWidth = 70;
float lineWidth = printWidth - numberWidth;
float lineLeft = leftMargin;
float numberLeft = leftMargin + lineWidth;
int items = 0;
foreach (DataRow dr in dt.Rows)
{
if (!dr[4].Equals(""))
items += Convert.ToInt32(dr[4].ToString());
else
items += 0;
}
noOfItems = items;
foreach (DataRow dr in dt.Rows)
{
Bitmap bt = null;
if (!dr[1].Equals(""))
{
if (!dr[4].Equals(""))
{
int nrcodes = Convert.ToInt32(dr[4].ToString());//in the 4th row the value means how many QRCodes should be generated
for (int i = 0; i < nrcodes; i++)
{
if (i % 5 != 0)
{
bt = GenerateQRCODE(dr[1].ToString());//dr[1] QRCode value
e.Graphics.DrawImage(bt, leftMargin, currentPosition, 200, 200);
e.Graphics.DrawString(dr[1].ToString(), fontNormal, normalColour, leftMargin + 40, currentPosition + 180); //dr[1] - text under QR Code
}
else
{
e.HasMorePages = true;
return;
}
currentPosition += 200;
}
}
}
}
// e.HasMorePages = true;
}
Yes, I need to print the same QR Code as many times as in the dr[4] column value. After that the next QR Code the same way.
In this case you need to keep track of the current DataRow and n copy to not repeat the same code for the same row and copy when you set e.HasMorePages = true;. For the copies, request a new page if the bottom of the current output block exceeds the e.MarginBounds.Bottom. To request a new page for each row, uncomment the last lines of the following example.
// +
using System.Drawing.Printing;
// ...
private int curRow = 0;
private int curCopy = 0;
// Or from where you call `.Print();`
// Button.Click event for example.
private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
curRow = 0;
curCopy = 0;
}
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
var curY = e.MarginBounds.Y;
using (var fontNormal = new Font("Arial", 12))
using (var sf = new StringFormat())
{
sf.Alignment = sf.LineAlignment = StringAlignment.Center;
int itemHeight = (int)fontNormal.GetHeight(e.Graphics) + 10;
for (int row = curRow; row < dt.Rows.Count; row++)
{
DataRow dr = dt.Rows[row];
if (!string.IsNullOrEmpty(dr.Field<string>(1)) &&
int.TryParse(dr.Field<string>(4)?.ToString(), out int copies))
{
for (int i = curCopy; i < copies; i++)
{
var imgRect = new Rectangle(e.MarginBounds.X, curY, 200, 200);
var labelRect = new Rectangle(
imgRect.X,
imgRect.Bottom,
imgRect.Width,
itemHeight);
if (curY + imgRect.Height + labelRect.Height >= e.MarginBounds.Bottom)
{
curCopy = i;
e.HasMorePages = true;
return;
}
using (var qrImage = GenerateQRCODE(dr[1].ToString()))
e.Graphics.DrawImage(qrImage, imgRect);
e.Graphics.DrawString(dr[1].ToString(),
fontNormal, Brushes.Black,
labelRect, sf);
curY = labelRect.Bottom + 30;
}
}
curRow = row + 1;
curCopy = 0;
// Uncomment if you want to start a new
// page for each row.
//if (row < dt.Rows.Count - 1)
//{
// e.HasMorePages = true;
// break;
//}
}
}
private StringReader myReader;
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
printDialog1.Document = printDocument1;
string strText = this.richTextBox1.Text;
myReader = new StringReader(strText);
if (printDialog1.ShowDialog() == DialogResult.OK)
{
printDocument1.Print();
}
}
private void printPrieviewToolStripMenuItem_Click(object sender, EventArgs e)
{
string strText = this.richTextBox1.Text;//read text for richtextbox
myReader = new StringReader(strText);
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
string line = null;
Font printFont = new System.Drawing.Font("Times New Roman", 8, FontStyle.Regular);
SolidBrush myBrush = new SolidBrush(Color.Black);
float linesPerPage = 0;
float topMargin = 590;
float yPosition = 590;
int count = 0;
float leftMargin = 70;
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
while (count < linesPerPage && ((line = myReader.ReadLine()) != null))
{
if (count == 0)
{
yPosition = 590;
topMargin = 590;
}
else
{
yPosition = 100;
topMargin = 100;
}
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
e.Graphics.DrawString(line, printFont, myBrush, leftMargin, yPosition, new StringFormat());
count++;
}
if (line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
myBrush.Dispose();
}
}
}
}
please where is my mistake.i want to print first page is top marigin is 590,and if more pages second page should be print top marigin is 100.
above given code is printing is ok but print marigin is not solved
help me the corection.
You are setting top margin based on count but count is not a page count, it is a line count. you need to keep a page count and use that.
Use a field to hold if it's the first page, remember to set it to true before calling printDocument1_PrintPage e.g:
bool Isfirstpage = true;
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
///.....
if (count == 0 && Isfirstpage)
{
yPosition = 590;
topMargin = 590;
Isfirstpage = false;
}
///....
I want to print the data from data grid. The code works well for the first page, but the commented lines do not works well and don't move to next page. Can anyone help fix this?
private void DrawFactorA4(object sender, PrintPageEventArgs ev)
{
for (int j = 0; j < GrdRDocument.Rows.Count; j++)
{
i += 2;
//draw data grid
s++;
if(s == 10)
{
//ev.HasMorePages = true; //this line doesn't work
s = 0;
i = 0;
}
else
{
ev.HasMorePages = false;
}
}
}
_
private void BtnPrint_Click(object sender, EventArgs e)
{
printFont = new Font("Arial", 12);
IEnumerable<PaperSize> paperSizes =
pd.PrinterSettings.PaperSizes.Cast<PaperSize>();
sizeA4 = paperSizes.First<PaperSize>(size => size.Kind == PaperKind.A4);
pd.DefaultPageSettings.Landscape = true;
pd.DefaultPageSettings.PaperSize = sizeA4;
pd.PrintPage += new PrintPageEventHandler(this.DrawFactorA4);
printPreviewDialog.Document = pd;
printPreviewDialog.ShowDialog();
}
Stop and read what you have:
printFont = new Font("Arial", 12);
Fonts are unmanaged resources; here you're instantating one and never disposing it. Maybe that's harmless in this particular situation, but this is a bad habit to get in to.
pd.PrintPage += new PrintPageEventHandler(this.DrawFactorA4);
DrawFactorA4 is going to be called for every page in your document. Inside DrawFactorA4:
for (int j = 0; j < GrdRDocument.Rows.Count; j++)
You iterate through every Row in GrdRDocument, regardless the number of rows or the size of your page. That is wrong; you have to stop after the page is filled. By the way, I hope GrdRDocument is a local copy of immutable data and you're not passing UI controls to the printing thread.
s++;
if(s == 10)
{
//ev.HasMorePages = true; //this line doesn't work
s = 0;
Your commented line would work fine. The problem is you set ev.HasMorePages = true and then ignore it; you set s = 0 and keep iterating; next iteration s!=10 so you:
ev.HasMorePages = false;
Read the PrintDocument docs; it has an example of printing more than one page. You should create a class to store all the unmanaged resources and page state. Make it IDisposable so they get disposed. Iterate through only the rows or whatever you want to print on each page. Something like:
class PrintStuff : IDisposable
{
readonly IEnumerable<Whatever> data;
readonly PrintDocument pd;
Font font;
private int currentIndex;
public PrintStuff(IEnumerable<Whatever> data)
{
this.data = data;
pd = new PrintDocument();
pd.BeginPrint += OnBeginPrint;
pd.PrintPage += OnPrintPage;
pd.EndPrint += OnEndPrint;
}
public void Print()
{
pd.Print();
}
public void Dispose()
{
pd.Dispose();
}
private void OnBeginPrint(object sender, PrintEventArgs args)
{
font = new Font(FontFamily.GenericSansSerif, 12F);
currentIndex = 0;
}
private void OnEndPrint(object sender, PrintEventArgs args)
{
font.Dispose();
}
private void OnPrintPage(object sender, PrintPageEventArgs args)
{
var x = Convert.ToSingle(args.MarginBounds.Left);
var y = Convert.ToSingle(args.MarginBounds.Top);
var lineHeight = font.GetHeight(args.Graphics);
while ((currentIndex < data.Count())
&& (y <= args.MarginBounds.Bottom))
{
args.Graphics.DrawWhatever(data.ElementAt(currentIndex), font, Brushes.Black, x, y);
y += lineHeight;
currentIndex++;
}
args.HasMorePages = currentIndex < data.Count();
}
}
I am new in C# and I am trying to print richTextBox's text into a page with size 58x297 but the text always starts from the middle of the page. I checked the printer properties but I couldn't find anything wrong. My aim is to print the text of my rich text box at the very left and top point of the page. I believe the problem is the initial spacing because of the size of my page that is 58x297 spacing is normal for an A4 page but not for mine.
This is the piece of work that I am trying to make work
private void button1_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(richTextBox1.Text);
documentToPrint.OriginAtMargins = false;
documentToPrint.PrintPage += new PrintPageEventHandler(Document_Print);
documentToPrint.Print();
}
}
private void Document_Print(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
StringReader reader = new StringReader(richTextBox1.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.richTextBox1.Font;
SolidBrush PrintBrush = new SolidBrush(Color.Black);
LinesPerPage = e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics);
while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null))
{
YPosition = LeftMargin + (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();
}
It would definitely be great if you have any ideas about. Thanks a lot ...
I am trying add a page when horizontal or the x position is greater than a counter in order to keep a right side margin. When I run the code I end up in an infinate loop of hundreds of pages all displaying the same first page graphics. Thinking it might have to do with my lack of understanding HasMorePages. I could use some help. Thanks.
public static class PrintWave
{
public static void PrintPreWave()
{
PrintDocument pd = new PrintDocument();
if (WaveTools.MySettings == null)
{
pd.DefaultPageSettings.Landscape = true;
}
else
{
pd.DefaultPageSettings = WaveTools.MySettings;
}
pd.OriginAtMargins = true;
pd.PrintPage += new PrintPageEventHandler(OnPrintPage);
PrintDialog dlg = new PrintDialog();
PrintPreviewDialog printPreviewDlg = new PrintPreviewDialog();
printPreviewDlg.Document = pd;
Form p = (Form)printPreviewDlg;
p.WindowState = FormWindowState.Maximized;
printPreviewDlg.ShowDialog();
}
private static void OnPrintPage(object sender, PrintPageEventArgs e)
{
string MyTag = string.Empty;
MyTag = WaveActions.ActiveId;
Wave MyWave = WaveHolder.FindWave(MyTag);
int MyCount = 0;
int xOffset = e.MarginBounds.Location.X;
int yOffset = e.MarginBounds.Location.Y;
if (MyWave != null)
{
Graphics g = e.Graphics;
g.SetClip(e.PageBounds);
Pen MyPen = new Pen(WaveTools.WaveColor, WaveTools.PenWidth);
float dx = (float)e.PageBounds.Width / MyWave.NumSamples;
float dy = (float)e.PageBounds.Height / 255;
if (MyWave.Normal == false)
{
g.ScaleTransform(dx, dy);
}
for (int i = 0; i < MyWave.NumSamples - 1; i++)
{
g.DrawLine(MyPen, i, MyWave.Data[i], i + 1, MyWave.Data[i + 1]);
MyCount = MyCount + 1;
if (MyCount > e.MarginBounds.Width)
{
e.HasMorePages = true;
MyCount = 0;
return;
}
else
{
e.HasMorePages = false;
return;
}
}
}
}
}
}
for (int i = 0; i < MyWave.NumSamples - 1; i++)
That's the core problem statement, you start at 0 every time PrintPage gets called. You need to resume where you left off on the previous page. Make the i variable a field of your class instead of a local variable. Implement the BeginPrint event to set it to zero.
The else clause inside the loop need to be deleted.