when I click on print preview button. it shows my listed items. but when I close print preview screen and add some more items and click on print preview. it shows only that items which I enter later. I clear my old added Items.
here is my code which I'm trying
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawString("Date: " + DateTime.Now.ToShortDateString(), new Font("Calibri", 11, FontStyle.Regular), Brushes.Black, new Point(300, 150));
e.Graphics.DrawString("Customer Name: " + customername.Text.Trim(), new Font("Calibri", 11, FontStyle.Regular), Brushes.Black, new Point(20, 150));
int yPos = 200;
int xPos = 20;
int brandyPos = 180;
for (int i = numberOfItemsPrintedSoFar; i < beltlist.Count; i++)
{
numberOfItemsPerPage++;
if (numberOfItemsPerPage <= 15 && count <= 3)
{
numberOfItemsPrintedSoFar++;
if (numberOfItemsPrintedSoFar <= beltlist.Count)
{
e.Graphics.DrawString(beltlist[i].BrandName, new Font("Calibri", 11, FontStyle.Regular), Brushes.Black, new Point(xPos, brandyPos));
brandyPos = yPos + 20;
e.Graphics.DrawString(beltlist[i].BeltSize.ToString() + "--" + beltlist[i].QTY.ToString(), new Font("Calibri", 11, FontStyle.Regular), Brushes.Black, new Point(20, yPos));
yPos += 20;
}
else
{
e.HasMorePages = false;
}
}
else
{
count++;
yPos = 180;
xPos += 150;
numberOfItemsPerPage = 0;
if (count > 3)
{
e.HasMorePages = true;
xPos = 20;
count = 1;
return;
}
}
}
}
Related
I have the following code for my BeginPrint, PrintPage and Click event. Firing the click event, its printing all pages. I would like to add a print range on button event that prints from-to range:
BeginPrint:
private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
curRow = 0;
curCopy = 0;
if (printrange)
{
((PrintDocument)sender).PrinterSettings.PrintRange = PrintRange.SomePages;
((PrintDocument)sender).PrinterSettings.FromPage = 1;
((PrintDocument)sender).PrinterSettings.ToPage = 1;
printrange = false;
}
}
PrintPage :
I'm generating QRCodes, borders and text in this method. Usually I have more than 2 pages with QRCodes. The problem is that it prints all pages
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
var curY = e.MarginBounds.Y;
var curX = e.MarginBounds.X + 30;//+ 10
Pen pen = new Pen(System.Drawing.ColorTranslator.FromHtml("#FFBD2D"), 1);
using (var fontNormal = new Font("Arial", 10))
using (var sf = new StringFormat())
{
sf.Alignment = sf.LineAlignment = StringAlignment.Center;
int itemHeight = (int)fontNormal.GetHeight(e.Graphics);
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(curX, curY, 156, 156);//e.MarginBounds.X
var labelRect = new Rectangle(
imgRect.X+180+20,//eltol
imgRect.Bottom-162,
itemHeight,
imgRect.Width);
using (var qrImage = GenerateQRCODE(dr[1].ToString()))
{
e.Graphics.DrawImage(RotateImage(qrImage, -90), imgRect);
}
SizeF labelSize = e.Graphics.MeasureString(dr[1].ToString(), fontNormal);
Bitmap stringmap = new Bitmap((int)labelSize.Height + 1, (int)labelSize.Width + 1);
Graphics gbitmap = Graphics.FromImage(stringmap);
gbitmap.TranslateTransform(0, labelSize.Width);
gbitmap.RotateTransform(-90);
gbitmap.DrawString(dr[1].ToString(), fontNormal, Brushes.Black, new PointF(0, 0), new StringFormat());
e.Graphics.DrawImage(stringmap, labelRect);
gbitmap.Dispose();
stringmap.Dispose();
e.Graphics.DrawLine(pen, curX, curY, curX, curY + 156);//57 |<
e.Graphics.DrawLine(pen, curX, curY + 156 , curX + 156 + 220, curY + 156);// _
e.Graphics.DrawLine(pen, curX + 156 + 220, curY + 156, curX + 156 + 220, curY);// >|
e.Graphics.DrawLine(pen, curX, curY, curX + 156 + 220, curY);// -
curX = imgRect.Right + 230; //horizontal gap
if (curX + imgRect.Width > e.MarginBounds.Right)
{
curX = e.MarginBounds.X + 30;
curY = labelRect.Bottom + 30;//55vertical gap
}
if (curY + imgRect.Height >= e.MarginBounds.Bottom)
{
curCopy = i + 1;
e.HasMorePages = true;
return;
}
}
}
curRow = row + 1;
curCopy = 0;
}
}
refreshprintbtn.Enabled = true;
printdialogbtn.Enabled = true;
}
In this click event I'm calling the print() method:
bool printrange = false;
private void printrangebtn_Click(object sender, EventArgs e)
{
printrange = true;
printDocument1.BeginPrint += printDocument1_BeginPrint;
printDocument1.PrintPage += printDocument1_PrintPage;
printDocument1.Print();
}
Thanks
You forgot to implement the PrintRange part in the PrintPage event. Just setting the PrintRange, FromPage, and ToPage properties doesn't mean that the printer knows which page should start with and which one should be the last. These properties exist to get the user inputs through the print dialogs or some setter methods and you need to use them as factors in your implementation.
For example, in PrintRange.SomePages case, use a class field to determine the target pages to print. Increment the field and print only if the value is within the .From and .To range.
// +
System.Drawing;
using System.Drawing.Printing;
// ...
private int curRow, curCopy, curPage;
public YourForm()
{
InitializeComponent();
printDocument1.BeginPrint += printDocument1_BeginPrint;
printDocument1.PrintPage += printDocument1_PrintPage;
}
private void printrangebtn_Click(object sender, EventArgs e)
{
printDocument1.PrinterSettings.PrintRange = PrintRange.SomePages;
printDocument1.PrinterSettings.FromPage = 1;
printDocument1.PrinterSettings.ToPage = 2;
printDocument1.Print();
}
private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
curRow = 0;
curCopy = 0;
curPage = 0;
// ...
}
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
var curY = e.MarginBounds.Y;
var curX = e.MarginBounds.X + 30;//+ 10
var doc = sender as PrintDocument;
using (var pen = new Pen(ColorTranslator.FromHtml("#FFBD2D")))
using (var fontNormal = new Font("Arial", 10))
using (var sf = new StringFormat())
{
sf.Alignment = sf.LineAlignment = StringAlignment.Center;
int itemHeight = (int)fontNormal.GetHeight(e.Graphics);
for (int row = curRow; row < dt.Rows.Count; row++)
{
curPage++;
var doPrint = doc.PrinterSettings.PrintRange != PrintRange.SomePages ||
(curPage >= doc.PrinterSettings.FromPage && curPage <= doc.PrinterSettings.ToPage);
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(curX, curY, 156, 156);//e.MarginBounds.X
var labelRect = new Rectangle(
imgRect.X + 180 + 20,//eltol
imgRect.Bottom - 162,
itemHeight,
imgRect.Width);
// If not, don't print and continue the calculations...
if (doPrint)
{
using (var qrImage = GenerateQRCODE(dr[1].ToString()))
e.Graphics.DrawImage(RotateImage(qrImage, -90), imgRect);
SizeF labelSize = e.Graphics.MeasureString(dr[1].ToString(), fontNormal);
Bitmap stringmap = new Bitmap((int)labelSize.Height + 1, (int)labelSize.Width + 1);
Graphics gbitmap = Graphics.FromImage(stringmap);
gbitmap.TranslateTransform(0, labelSize.Width);
gbitmap.RotateTransform(-90);
gbitmap.DrawString(dr[1].ToString(), fontNormal, Brushes.Black, new PointF(0, 0), new StringFormat());
e.Graphics.DrawImage(stringmap, labelRect);
gbitmap.Dispose();
stringmap.Dispose();
e.Graphics.DrawLine(pen, curX, curY, curX, curY + 156);//57 |<
e.Graphics.DrawLine(pen, curX, curY + 156, curX + 156 + 220, curY + 156);// _
e.Graphics.DrawLine(pen, curX + 156 + 220, curY + 156, curX + 156 + 220, curY);// >|
e.Graphics.DrawLine(pen, curX, curY, curX + 156 + 220, curY);// -
}
curX = imgRect.Right + 230; //horizontal gap
if (curX + imgRect.Width > e.MarginBounds.Right)
{
curX = e.MarginBounds.X + 30;
curY = labelRect.Bottom + 30;//55vertical gap
}
if (curY + imgRect.Height >= e.MarginBounds.Bottom)
{
if (!doPrint) break;
curCopy = i + 1;
e.HasMorePages = true;
return;
}
}
}
if (!doPrint)
{
curX = e.MarginBounds.X;
curY = e.MarginBounds.Y;
}
curRow = row + 1;
curCopy = 0;
}
}
refreshprintbtn.Enabled = true;
printdialogbtn.Enabled = true;
}
Side Notes
You shouldn't add handlers for the PrintDocument events each time you click a Button unless you remove the current handlers first in the EndPrint for example. Just add them once as shown in the Form's ctor or Load event.
System.Drawing.Pen is a disposable object so you need to dispose of it as well. Create it with the using statement or pass an instance using (pen) ... or call the .Dispose(); method explicitly. Do the same for any object implements the IDisposable interface.
I want to print 50 labels per sheet (5 columns and 10 rows). When it goes to the 11th row it should switch to the next page. I have tried e.hasMorePages in several ways, but sometimes it gets overlapped on the same page.
Here is my code:
private void MakingLabel(int curentIndex,List<BarcodesSpecs> List)
{
int ListRows = List.Count;
BarcodesSpecs barcodesSpecs = List.ElementAt(curentIndex);
BarCode_ItemCode = barcodesSpecs.ItemCodeMain;
BarCode_Description = barcodesSpecs.Description;
BarCode_SalePrice = barcodesSpecs.SalePrice;
BarCode_Size = barcodesSpecs.Size;
BarCode_Colour = barcodesSpecs.Colour;
barCode_LabelToPrint = Convert.ToInt16(barcodesSpecs.QtyToPrint);
}
int xCord = 0, yCord = 0;
int CurentIndex = 0;
int MaxCharactersInString = 26;
private void printBarcodes_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
for (CurentIndex = 0; CurentIndex < BcList.Count; CurentIndex++)
{
MakingLabel(CurentIndex, BcList);
for (int i = 0; i < barCode_LabelToPrint; i++) //// making Copies means How many Labels Of this Item Needed
{
if (xCord >= 750)
{
xCord = 0;
yCord += 115;
}
if (BarCode_Description.Length > MaxCharactersInString)
{
BarCode_Description = BarCode_Description.Substring(0, MaxCharactersInString);
}
e.Graphics.DrawString("ALPIAL SUITING", new Font("Arial", 10, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 10));
e.Graphics.DrawString("Rs" + BarCode_SalePrice + "/-", new Font("Arial", 14, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 21));
e.Graphics.DrawString("Size: " + BarCode_Size + " Colour: " + BarCode_Colour, new Font("Arial", 07, FontStyle.Regular), Brushes.Black, new Point(xCord, yCord + 42));
e.Graphics.DrawString(BarCode_Description, new Font("Arial", 07, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 52));
e.Graphics.DrawString(BarCode_ItemCode, new Font("Arial", 06, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 62));
Zen.Barcode.Code128BarcodeDraw barcode = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
e.Graphics.DrawImage(barcode.Draw(BarCode_ItemCode, 25), xCord, yCord + 72);
xCord += 160;
}
}
}
The result I am getting is in the picture, any help will be appreciated thanks!
Somewhere along the line, you will need to check if yCord is beyond the bottom of the page. If it is, you need to set HasMorePages to true and exit the PrintPage handler. It will be called again for the next page. You'll have to keep track of which labels you have already printed outside the PrintPage handler and continue from that point.
Here's a sample I did to simulate labels printing. I only drew a square to represent the label. I had to do a little math to figure out the spacing so you will likely have to adjust this for your situation.
private static void doPrintPreview()
{
var pd = new PrintDocument();
pd.PrintPage += pd_PrintPage;
var prv = new PrintPreviewDialog();
prv.Document = pd;
prv.ShowDialog();
}
//Units are in 1/100 of an inch
private static float leftMargin = 100f; //Page margins
private static float rightMargin = 750f;
private static float topMargin = 100f;
private static float bottomMargin = 1000f;
private static int numLabelsToPrint = 200; //How many we want to print
private static int numLabelsPrinted = 0; //How many we have already printed
private static float labelSizeX = 75; //Label size
private static float labelSizeY = 75f;
private static float labelGutterX = 7.14f; //Space between labels
private static float labelGutterY = 7.5f;
static void pd_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.PageUnit = GraphicsUnit.Display; //Units are 1/100 of an inch
//start at the left and top margin of the page for a new page
float xPos = leftMargin;
float yPos = topMargin;
using (var p2 = new Pen(Brushes.Red, 3.0f))
{
//While there are still labels to print
while (numLabelsPrinted < numLabelsToPrint)
{
//Draw the label (i just drew a square)
e.Graphics.DrawRectangle(Pens.Red, xPos, yPos, labelSizeX, labelSizeY);
numLabelsPrinted++;
//Set the x position for the next label
xPos += (labelSizeX + labelGutterX);
//If the label will be printed beyond the right margin
if ((xPos + labelSizeX) > rightMargin)
{
//Reset the x position back to the left margin
xPos = leftMargin;
//Set the y position for the next row of labels
yPos += (labelSizeY + labelGutterY);
//If the label will be printed beyond the bottom margin
if ((yPos + labelSizeY) > bottomMargin)
{
//Reset the y position back to the top margin
yPos = topMargin;
//If we still have labels to print
if (numLabelsPrinted < numLabelsToPrint)
{
//Tell the print engine we have more labels and then exit.
e.HasMorePages = true;
//Notice after setting HasMorePages to true, we need to exit from the method.
//The print engine will call the PrintPage method again so we can continue
//printing on the next page.
break; //you could also just use return here
}
}
}
}
}
}
I'm writing a program in C# which takes information of items from Listview and print it based on the quantity of these items. My problem is that I would like to print a document in multiple pages in c#.
Here is my code:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
//frame
e.Graphics.DrawRectangle(Pens.Black, 30, 30, 757, 1080);
//rows
e.Graphics.DrawLine(Pens.Black, 30, 184, 787, 184);
e.Graphics.DrawLine(Pens.Black, 30, 338, 787, 338);
e.Graphics.DrawLine(Pens.Black, 30, 492, 787, 492);
e.Graphics.DrawLine(Pens.Black, 30, 646, 787, 646);
e.Graphics.DrawLine(Pens.Black, 30, 800, 787, 800);
e.Graphics.DrawLine(Pens.Black, 30, 955, 787, 955);
//columns
e.Graphics.DrawLine(Pens.Black, 282, 30, 282, 1110);
e.Graphics.DrawLine(Pens.Black, 534, 30, 534, 1110);
int rows_loc = 35;
int cols_loc = 70;
int lable_index = 0;
foreach (ListViewItem item in listView1.Items)
{
for (int quantity = 1; quantity < (Convert.ToInt32(item.SubItems[1].Text) + 1); quantity++)
{
Font font = new System.Drawing.Font("Arial", 16);
SolidBrush black = new SolidBrush(Color.Black);
Zen.Barcode.Code128BarcodeDraw barcode1 = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
Image barcode_image = barcode1.Draw(item.SubItems[2].Text, 20);
e.Graphics.DrawImage(barcode_image, 40f + cols_loc, 29f + rows_loc);
e.Graphics.DrawString(item.Text, font, black, 60f + cols_loc, 0f + rows_loc);
lable_index++;
row_index = (int)(lable_index / 3);
col_index = lable_index % 3;
rows_loc = 35 + ((row_index) * 155);
cols_loc = 70 + (250 * col_index);
if (rows_loc >= e.PageSettings.PrintableArea.Height)
{
e.HasMorePages = true;
rows_loc = 35;
return;
}
else
{
e.HasMorePages = false;
}
}
}
}
But got the page looks like the figure below with infinite number of pages! I would be very appreciated if someone can help.
Thanks
Printer prints every odd page in portrait orientation.
private void Form1_Loaded(object sender, EventArgs e)
{
PaperSize ps = new PaperSize("Custom", 700, 325);
printDocument.DefaultPageSettings.PaperSize = ps;
label1.Text = Convert.ToString(printDocument.DefaultPageSettings.PaperSize);
//printDocument.DefaultPageSettings.Landscape = true;
printDocument.PrinterSettings.DefaultPageSettings.Landscape = true;
}
private void DrawGridBody(Graphics g, int y_value)
{
int x_value;
for (int i = 0; (i < NUM_ROWS_PER_PAGE) && ((i+m_printedRows) < ((DataTable)dataGridView.DataSource).Rows.Count); ++i)
{
DataRow dr = ((DataTable)dataGridView.DataSource).Rows[i + m_printedRows];
x_value = 0;
string text = dr.ItemArray.ElementAt(0).ToString();
g.DrawString(text+"**", this.Font, Brushes.Black, (float)x_value, (float)y_value + 10f);
y_value += ROW_HEIGHT;
g.DrawString("page " + Convert.ToString(m_printedRows), new Font("Lucidia Console", 14, FontStyle.Bold), Brushes.Black, 60, 10);
g.DrawString("1 " + dr.ItemArray.ElementAt(0).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(370, 20));
g.DrawString("2 " + dr.ItemArray.ElementAt(0).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(390, 46));
g.DrawString("3 " + dr.ItemArray.ElementAt(0).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(30, 40));
g.DrawString(dr.ItemArray.ElementAt(1).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(70, 180));
g.DrawString(dr.ItemArray.ElementAt(2).ToString() + " " + dr.ItemArray.ElementAt(3).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(70, 202));
g.DrawString(dr.ItemArray.ElementAt(4).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(70, 224));
g.DrawString(dr.ItemArray.ElementAt(5).ToString(), new Font("Lucidia Console", 10), Brushes.Black, new Point(550, 285));
g.DrawString("***********", new Font("Lucidia Console", 10), Brushes.Black, new Point(550, 300));
g.DrawString("***********", new Font("Lucidia Console", 10), Brushes.Black, new Point(550, 315));
}
m_printedRows += NUM_ROWS_PER_PAGE;
printDocument.PrinterSettings.DefaultPageSettings.Landscape = true;
printDocument.DefaultPageSettings.Landscape = true;
}
private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int rowPosition = SPACE_ABOVE_HEADER;
rowPosition += ROW_HEIGHT;
// draw each row
DrawGridBody(e.Graphics, rowPosition);
// see if there are more pages to print
if (MoreRowToPrint())
e.HasMorePages = true;
else
m_printedRows = 0;
}
private bool MoreRowToPrint()
{
return ((DataTable)dataGridView.DataSource).Rows.Count > m_printedRows;
}
Although there are some tutorials on web, I'm still lost on why this doesn't print multiple pages correctly. What am I doing wrong?
public static void printTest()
{
PrintDialog printDialog1 = new PrintDialog();
PrintDocument printDocument1 = new PrintDocument();
printDialog1.Document = printDocument1;
printDocument1.PrintPage +=
new PrintPageEventHandler(printDocument1_PrintPage);
DialogResult result = printDialog1.ShowDialog();
if (result == DialogResult.OK)
{
printDocument1.Print();
}
}
static void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics graphic = e.Graphics;
SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font("Courier New", 12);
e.PageSettings.PaperSize = new PaperSize("A4", 850, 1100);
float pageWidth = e.PageSettings.PrintableArea.Width;
float pageHeight = e.PageSettings.PrintableArea.Height;
float fontHeight = font.GetHeight();
int startX = 40;
int startY = 30;
int offsetY = 40;
for (int i = 0; i < 100; i++)
{
graphic.DrawString("Line: " + i, font, brush, startX, startY + offsetY);
offsetY += (int)fontHeight;
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
}
else {
e.HasMorePages = false;
}
}
}
You can find an example of this code's printed result here: Printed Document
You never return from the loop. Change it to:
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
return; // you need to return, then it will go into this function again
}
else {
e.HasMorePages = false;
}
In addition you need to change the loop to start at the current number on the 2nd page instead of restarting with i=0 again.