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.
Related
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;
}
}
}
}
I want to print all item's Barcode using PrintPreviewDialog. Written code works fine but the problem is on ending first page i called e.HasMorePages = true which creates 2nd page but not printing 2nd page. it means 2nd page got empty /blank. As you can see in below pic, at last line Barcode got cropped automatically and not print remaining Barcodes on 2nd page. Kindly help how to print remaining Barcode on 2nd page.
as you can see in above pic, the last line got cropped automatically and 2nd page not printing and got empty page.
PrintPreviewDialog code;
pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(this.PrintBarcodeEvent_PrintPage);
System.Windows.Forms.PrintDialog pdd = new System.Windows.Forms.PrintDialog();
pdd.Document = pd;
System.Windows.Forms.DialogResult result = pdd.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
System.Windows.Forms.PrintPreviewDialog pp = new System.Windows.Forms.PrintPreviewDialog();
pp.Document = pd;
result = pp.ShowDialog();
//pd.Print();
}
Event:
// The PrintPage event is raised for each page to be printed.
private void PrintBarcodeEvent_PrintPage(object sender, PrintPageEventArgs e)
{
int startX = 5;
int startY = 5;
Database db = new Database();
db.DBOpen();
int NBbarcode_perLine = 5;
int numbarcode = 0;
int barcodePerPage = 35;
int countBarcodePerPage = 0;
for (int i = 0; i < listTobePrint.Count; i++)
{
String code = listTobePrint[i].Code;
String name = db.GetByValue(Database.TABLE_ITEMS, Database.CODE_ITEMS, code, 2);
String price = db.GetByValueForInt(Database.TABLE_ITEMS, Database.CODE_ITEMS, code, 8);
Font printFont = new Font("Arial", 10.0f);
e.Graphics.DrawString("Phulkari by VIRSA", printFont, System.Drawing.Brushes.Black,
startX, startY, new StringFormat());
int x2 = startX + 3;
int y2 = startY + 15;
e.Graphics.DrawImage(Util.ImageWpfToGDI(Util.GenerateBarcode(code)), x2, y2, 100, 50);
int x3 = startX;
int y3 = y2 + 50;
e.Graphics.DrawString(code, printFont, System.Drawing.Brushes.Black,
x3, y3, new StringFormat());
int x4 = startX;
int y4 = y3 + 15;
e.Graphics.DrawString(name, printFont, System.Drawing.Brushes.Black,
x4, y4, new StringFormat());
int x5 = startX;
int y5 = y4 + 15;
e.Graphics.DrawString("Rs." + price, printFont, System.Drawing.Brushes.Black,
x5, y5, new StringFormat());
numbarcode++;
countBarcodePerPage++;
if (numbarcode < NBbarcode_perLine)
startX += 150;
else
{
startX = 5;
startY += 150; // space between 2 barcode in vertical (upper left). you have to adjust)
numbarcode = 0;
}
if (countBarcodePerPage >= barcodePerPage)
{
//MessageBox.Show(countBarcodePerPage.ToString());
e.HasMorePages = true;
//startX = 5;
//startY = 5;
} else
{
e.HasMorePages = false;
}
}
db.DBClose();
listTobePrint.Clear();
}
you have to create a global variable countbarcode (not local to PrintPage) or static and initialise To zéro.
Each time you set e.HasMorePages to true, the event PrintPage is called
Its not a problem for a test, but i think you should put the db.open in event BeginPrint and db.close in event EndPrint . the database is open and close each time a page is printed. (maybe its not really important, but you avoid to recreate the same variable db and waste meory)
private void PrintBarcodeEvent_PrintPage(object sender, PrintPageEventArgs e)
{
int startX = 5;
int startY = 5;
Database db = new Database();
db.DBOpen();
int NBbarcode_perLine = 5;
int numbarcode = 0;
int barcodePerPage = 35;
int countBarcodePerPage = 0;
int totalcodebar = listTobePrint.Count;
for (int i = 0; i < barcodePerPage; i++)
{
String code = listTobePrint[countbarcode].Code;
String name = db.GetByValue(Database.TABLE_ITEMS, Database.CODE_ITEMS, code, 2);
String price = db.GetByValueForInt(Database.TABLE_ITEMS, Database.CODE_ITEMS, code, 8);
Font printFont = new Font("Arial", 10.0f);
e.Graphics.DrawString("Phulkari by VIRSA", printFont, System.Drawing.Brushes.Black,
startX, startY, new StringFormat());
int x2 = startX + 3;
int y2 = startY + 15;
e.Graphics.DrawImage(Util.ImageWpfToGDI(Util.GenerateBarcode(code)), x2, y2, 100, 50);
int x3 = startX;
int y3 = y2 + 50;
e.Graphics.DrawString(code, printFont, System.Drawing.Brushes.Black,
x3, y3, new StringFormat());
int x4 = startX;
int y4 = y3 + 15;
e.Graphics.DrawString(name, printFont, System.Drawing.Brushes.Black,
x4, y4, new StringFormat());
int x5 = startX;
int y5 = y4 + 15;
e.Graphics.DrawString("Rs." + price, printFont, System.Drawing.Brushes.Black,
x5, y5, new StringFormat());
numbarcode++;
countbarcode++;
if (numbarcode < NBbarcode_perLine)
startX += 150;
else
{
startX = 5;
startY += 150; // space between 2 barcode in vertical (upper left). you have to adjust)
numbarcode = 0;
}
if (countbarcode == totalcodebar) break;
if (i == barcodePerPage - 1)
{
db.DBClose();
e.HasMorePages = true;
return;
}
}
e.HasMorePages = false;
db.DBClose();
listTobePrint.Clear();
}
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 want create a control that draws a table in panel . My code is:
public class PanelZ : System.Windows.Forms.Panel
{
public static void Draw()
{
Panel p = new Panel();
p.Width = 200;
p.Height = 200;
Graphics g = p.CreateGraphics();
Pen mypen = new Pen(Brushes.Black, 1);
Font myfont = new Font("tahoma", 10);
int lines = 9;
float x = 0;
float y = 0;
float xSpace = p.Width / lines;
float yspace = p.Height / lines;
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, x, y, x, p.Height);
x += xSpace;
}
x = 0f;
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, x, y, p.Width, y);
y += yspace;
}
}
..but it dosen't draw a table; so what should I do?
This will work. But the numbers ought to be properties, as should the pen and then some.. Also: Properties ought to start with an uppercase letter.
public class PanelZ : System.Windows.Forms.Panel
{
public PanelZ() // a constructor
{
Width = 200;
Height = 200;
DoubleBuffered = true;
lines = 9;
}
public int lines { get; set; } // a property
protected override void OnPaint(PaintEventArgs e) // the paint event
{
base.OnPaint(e);
Graphics g = e.Graphics;
Pen mypen = new Pen(Brushes.Black, 1);
Font myfont = new Font("tahoma", 10);
float x = 0;
float y = 0;
float xSpace = Width / lines;
float yspace = Height / lines;
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, x, y, x, Height);
x += xSpace;
}
for (int i = 0; i < lines + 1; i++)
{
g.DrawLine(mypen, 0, y, Width, y);
y += yspace;
}
}
}
At work in VS:
Note that this only colors pixels. There is no useful grid there, just pixels with color.. So, if you actually want to use the Font you define you will have to calculate the coodordinates and the bounding boxes.
please some one help me , i have to print a document in multiple pages in c#, i went through internet then used this code but not working, (loop is again start after printing one page )
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
try
{
Graphics graphic = e.Graphics;
SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font("Courier New", 12);
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;
return;
}
else
{
e.HasMorePages = false;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Whenever you set e.HasMorePages = true, it will just fire the printDocument1_PrintPage() event handler again. You need to keep a class variable for i, so that it won't restart at 0 every time the next page prints. Don't declare it locally inside the event handler.
private class MyPrinter
{
private int i = 0;
private void Print()
{
i = 0;
printDocument1.Print();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
.....
.....
.....
while (i < 100)
{
graphic.DrawString("Line: " + i, font, brush, startX, startY + offsetY);
offsetY += (int)fontHeight;
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
return;
}
else
{
e.HasMorePages = false;
}
i = i + 1;
}
}
}