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();
}
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 need to print all inventory items Barcodes at once. For print, i've select all items by Button click and do print using DrawString or DrawImage function which works fine but the problem if name of items are too long then i have clip width to 100px and text got wrap and print function call but on printing 2nd line, the items starting Y points unable to identify which creates problem. if i identifying 1st row height correctly then i can set 2nd rows Y coordinates accordingly that problem can be resolved but i dont know how to do. As you can see result in below image.
*The problem is in this piece of code:
if (numbarcode < NBbarcode_perLine)
startX += 150;
else
{
//MessageBox.Show(rectangleHeight.ToString());
startX = 5;
startY += 150; // space between 2 lines
numbarcode = 0;
}
code:
// 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 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("Rs." + price, printFont, System.Drawing.Brushes.Black,
x4, y4, new StringFormat());
// Measure string.
SizeF stringSize = new SizeF();
stringSize = e.Graphics.MeasureString(name, printFont);
int width = (int)stringSize.Width;
int height = (int)stringSize.Height;
//MessageBox.Show(width.ToString() + ", Height: "+height);
int x5 = startX;
int y5 = y4 + 15;
RectangleF rectangle = new RectangleF(x5, y5, 100, 0);
int rectangleWidht = (int)rectangle.Width;
int rectangleHeight = (int)rectangle.Height;
//MessageBox.Show(rectangleHeight.ToString());
e.Graphics.DrawString(name, printFont, System.Drawing.Brushes.Black,
rectangle, new StringFormat());
numbarcode++;
countbarcode++;
if (numbarcode < NBbarcode_perLine)
startX += 150;
else
{
//MessageBox.Show(rectangleHeight.ToString());
startX = 5;
startY += 150; // space between 2 lines
numbarcode = 0;
}
if (countbarcode == totalcodebar) break;
if (i == barcodePerPage - 1)
{
e.HasMorePages = true;
return;
}
}
countbarcode = 0;
e.HasMorePages = false;
db.DBClose();
}
one first solution is:
decrease one line of barcode and increase the space between two lines: (because you have the risk to have a cut line in bottom of page)
int barcodePerPage = 30;//instead of 35
and you increase the space betwween two line
if (numbarcode < NBbarcode_perLine)
startX += 150;
else
{
//MessageBox.Show(rectangleHeight.ToString());
startX = 5;
startY += 200; // ***** space between 2 lines increased
numbarcode = 0;
}
this solution has the advantage to have the same number of barcode per page
another solution will be to calcul the number of char of next 35 barcode and following the number of char of item you choose the first way to print 35 barcode or if char is too long, the second way to print 30 barcode. if you dont know to do that i could help you
This solution could have different number of barcode per page
Another solution is to choose a little font for the item (arial 8 for example) and you could win space
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;
}
}
}
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.