Print title on each page c# - c#

I have this list with 5 indices and I want to print the title on a new page, what do I write so it prints it on the next page?
list<> // 5 indices
void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics graphic = e.Graphics;
float fontHeight = font.GetHeight();
int startX = 10;
int startY = 10;
for (int i = 0; i < list.Count; i++)
{
graphic.DrawString(list[i].Title, new Font("Courier New", 18), new SolidBrush(Color.Black), startX, startY);
}
}

You have to maintain an instance variable which points to the current index of the item in the list to display , and increment it every time a page is printed.
int currIndex = 0;
void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics graphic = e.Graphics;
float fontHeight = font.GetHeight();
int startX = 10;
int startY = 10;
graphic.DrawString(list[currIndex++].Title, new Font("Courier New", 18), new SolidBrush(Color.Black), startX, startY);
if(currIndex == list.Count)
{
e.HasMorePages = false;
currIndex = 0;
}
else
{
e.HasMorePages = true;
}
}

The printDocument object calls that same PrintPage() method for every page. If you want different content to appear on different pages, you need code that lives outside of that method to store the current state, and code within the method to check that state and resume/continue printing based on the state you stored outside of the method.
If you have instructions in the PrintPage() to print the title, then the title will be printed. End of story.

Related

C# how to print out an array of PictureBox in multiple pages

using C#, I wrote the below code to print out images in an array (size = totalToPrint) of Picturebox pictureBoxArr[] each in size of 100x100 pixel. I want to print them vertically with the 20-pixel distance between them heightDistanceBetweenImages the problem is that it only prints on 1 page (say letter size) no matter how many images ( then it only prints 8 images and dismisses the rest). How can I solve this problem, and print it on multiple pages?
int totalToPrint;
int xFirstAncorPoint = 100;
int yFirstAncorPoint = 100;
int ImagSize = 100; // Squre of 100x100 pixel
int heightDistanceBetweenImages = 20;
PrintDialog pd = new PrintDialog();
PrintDocument pDoc = new PrintDocument();
pDoc.PrintPage += PrintPicture;
pd.Document = pDoc;
if (pd.ShowDialog() == DialogResult.OK)
{
pDoc.Print();
}
}
public void PrintPicture(Object sender, PrintPageEventArgs e)
{
Bitmap bmp1 = new Bitmap(ImagSize , totalToPrint * (ImagSize + heightDistanceBetweenImages));
for (int i = 0; i < totalToPrint; i++)
{
pictureBoxArr[i].DrawToBitmap(bmp1, new Rectangle(0, i * (heightDistanceBetweenImages + ImagSize), pictureBoxArr[0].Width, pictureBoxArr[0].Height));
}
e.Graphics.DrawImage(bmp1, xFirstAncorPoint, yFirstAncorPoint);
bmp1.Dispose();
}
You are about half way there. PrintDocument would be your future reference.
The PrintPage gives you more than just a drawing space; it also has your page bounds, page margins, etc. It also has HasMorePages property that you set if you need to print more pages. This property defaults to false, so you were only printing 1 page. Also if anything is outside the bounds of the page, it would not print that. With a little change here and there, you would end up with something like this.
// using queue to manage images to print
Queue<Image> printImages = new Queue<Image>();
int totalToPrint;
int xFirstAncorPoint = 100;
int yFirstAncorPoint = 100;
int ImagSize = 100; // Squre of 100x100 pixel
int heightDistanceBetweenImages = 20;
private void btnPrintTest_Click(object sender, EventArgs e) {
PrintDialog pd = new PrintDialog();
PrintDocument pDoc = new PrintDocument();
pDoc.PrintPage += PrintPicture;
pd.Document = pDoc;
if (pd.ShowDialog() == DialogResult.OK) {
// add image references to printImages queue.
for (int i = 0; i < pictureBoxArr.Length; i++) {
printImages.Enqueue(pictureBoxArr[i].Image);
}
pDoc.Print();
}
}
private void PrintPicture(object sender, PrintPageEventArgs e) {
int boundsHeight = e.MarginBounds.Height; // Get height of bounds that we are expected to print in.
int currentHeight = yFirstAncorPoint;
while (currentHeight <= boundsHeight && printImages.Count > 0) {
var nextImg = printImages.Peek();
int nextElementHeight = nextImg.Height + heightDistanceBetweenImages;
if (nextElementHeight + currentHeight <= boundsHeight) {
e.Graphics.DrawImage(nextImg, new PointF(xFirstAncorPoint, currentHeight + heightDistanceBetweenImages));
printImages.Dequeue();
}
currentHeight += nextElementHeight;
}
// how we specify if we may have more pages to print
e.HasMorePages = printImages.Count > 0;
}
Hopefully this gets you on the right path and with some minor tweaks for your code, you will have what you need.

Full page not printing

Thats my printpage Event Handler Code
private void printDocument2_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int yaxis = 0;
Font font = new Font("Arial", 12, FontStyle.Bold);
for (int i = 0; i < 300; i++)
{
e.Graphics.DrawString("Store Inventory Report", font, Brushes.Black, 0, yaxis);
yaxis += 30;
}
}
This code only prints line 37 times. . . its not printing full page. . i generates its pdf, pdf also have line 37 times.
With full printing did you mean printing all the 300 lines base on your code? If it is you should set the parameter:
e.HasMorePages = true;
Set it to false when you reach the condition where all contents are already printed.
For your case it would be something like this:
private int startIndex = 0; //Keeps track of printed index
private int limit = 300; //Limit of items to print
private void printDocument2_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int yaxis = 0;
Font font = new Font("Arial", 12, FontStyle.Bold);
for (int i = startIndex; i < limit; i++)
{
e.Graphics.DrawString("Store Inventory Report", font, Brushes.Black, 0, yaxis);
yaxis += 30;
//Reaches bottom? break the loop
if (yaxis > e.PageBounds.Bottom)
{
startIndex = i + 1; //Set to next page's data index
break;
}
}
//Still has pages?
e.HasMorePages = startIndex < limit;
}

How to print the values of datagridview in c#? [duplicate]

This question already has answers here:
How to print values from a DataGridView control
(3 answers)
Closed 8 years ago.
i want to print entire rows of an DGV.
this should be done by extracting the values not taking picture...(if you don't understand please comment below)
is there any way i can do this?
Still facing problem...
https://drive.google.com/file/d/0BxqCNfHpYEJlUVg3VW5aZlpHMlk/view?usp=sharing
Here is an absolutely minimal code example.
It prints all rows of a dgv, including simple headers and footers..
You need to add a PrintDocument printDocument1 to your form.
Also a Button cb_printPreview.
// a few variables to keep track of things across pages:
int nextPageToPrint = -1;
int linesOnPage = -1;
int linesPrinted = -1;
int maxLinesOnPage = -1;
private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
// for each fresh page:
linesOnPage = 0;
nextPageToPrint++;
// a short reference to the DataGridView we want to print
DataGridView DGV = yourDataGridView;
// I prefer mm, pick your own unit!
e.Graphics.PageUnit = GraphicsUnit.Millimeter;
// I want to print the columns at these fixed positions
// the first one is the left margin,
// the last one a dummy at the right page margin
int[] tabStops = new int[4] {15, 30, 100, 190};
// I want only one column to be right-aligned:
List<int> rightAlignedCols = new List<int>() { 1 };
// we need to keep track of the horizontal position
// this is also the top margin:
float y = 35f;
// we add a little space between the lines:
float leading = 1.5f;
// we will need to measure the texts we print:
SizeF size = Size.Empty;
// we use only one font:
using (Font font = new Font("Consolas", 13f))
{
// a simple header:
e.Graphics.DrawString("List " + printDocument1.DocumentName,
font, Brushes.Black, 50, y);
y += size.Height + 15;
// I loop over the all rows:
for (int row = linesPrinted; row < DGV.Rows.Count; row++)
{
// I print a light gray bar over every second line:
if (row % 2 == 0)
e.Graphics.FillRectangle(Brushes.Gainsboro,
tabStops[0], y - leading / 2, e.PageBounds.Width - 25, size.Height);
// I print all (3) columns in black, unless they're empty:
for (int col = 0; col < DGV.ColumnCount; col++)
if (DGV[0, row].Value != null)
{
string text = DGV[col, row].FormattedValue.ToString();
size = e.Graphics.MeasureString(text, font, 9999);
float x = tabStops[col];
if (rightAlignedCols.Contains(col) )
x = tabStops[col + 1] - size.Width;
// finally we print an item:
e.Graphics.DrawString(text, font, Brushes.Black, x, y);
}
// advance to next line:
y += size.Height + leading;
linesOnPage++;
linesPrinted++;
if (linesOnPage > maxLinesOnPage) // page is full
{
e.HasMorePages = true; // more to come
break; // leave the rows loop!
}
}
e.Graphics.DrawString("Page " + nextPageToPrint, font,
Brushes.Black, tabStops[3] -20, y + 15);
}
}
private void cb_printPreview_Click(object sender, EventArgs e)
{
PrintPreviewDialog PPVdlg = new PrintPreviewDialog();
PPVdlg.Document = printDocument1;
PPVdlg.ShowDialog();
}
private void printDocument1_BeginPrint(object sender,
System.Drawing.Printing.PrintEventArgs e)
{
// create a demo title for the page header:
printDocument1.DocumentName = " Suppliers as of "
+ DateTime.Now.ToShortDateString();
// initial values for a print job:
nextPageToPrint = 0;
linesOnPage = 0;
maxLinesOnPage = 30;
linesPrinted = 0;
}
The actual printing can be triggered from the PrintPreviewDialog.
There is also a PrintDialog and a PrintPreview control for more options.
Obviously one can add many more things, including graphics, multiple fonts etc, but this should give you an idea.. For full tutorials please look refer to the WWW & MSDN!

Append a Rectangle to the old Rectangles

Hye there I am new to C# and learning it to my own. My problem is that I want to append a new rectangle to the old rectangles and move them all using a timer my code is:
Rectangle[] rec;
int rec_part = 4;
int rec_x = 0;
Color c = Color.FromArgb(255, 255, 255);
public Form1()
{
InitializeComponent();
rec = new Rectangle[rec_part];
for (int i = 0; i < rec_part; i++)
{
rec_x += 43;
rec[i] = new Rectangle(rec_x, 100, 40,40);
}
}
it will initialize 4 Rectangles, then:
Graphics g;
private void Form1_Paint(object sender, PaintEventArgs e)
{
g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
for (int i = 0; i < rec_part; i++)
g.FillRectangle(new SolidBrush(Color.Red), rec[i]);
}
This will draw 4 Rectangle Controls on the Form, then:
int speed = 2;
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < rec.Length; i++)
{
rec[i].X += speed;
rec_part += 1; \\Here I want to append a new Rectangle to the existing rectangles
\\ the array size is to increment so that that a new rectangle will append
}
Refresh();
}
But the problem is that an "index out of range" exception has been thrown within my code but if I use my timer as:
int speed = 2;
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < rec.Length; i++)
{
rec[i].X += speed;
if (rec_part == rec.Length)
rec_part = 0;
else
rec_part += 1;
}
Refresh();
}
All works fine with this code, but it starts blinking so much so that one can unable to watch it perfectly, and every time it draws new rectangles in number of 4 whereas I want to append a new rectangle!
Sorry for my English. Can somebody help me out sorting thing problem? Thanks.
I advise you adding the rectangles to a list instead of an array.
I also advice you not to use winforms for drawing rectangles WPF is way faster in drawing lots of stuff it's a bit more complicated but it's faster.
reply if you need any code samples and i'll update my answer
This is my code:
rectangles2[i] = rectangleupdated(rectangles2[i]);
Rectangles2 is a list of rectangles, rectangleupdated has as parameters an rectangles then it modifys the rectangles like this:
Rectangle rectangleupdated(Rectangle rect){
return rect.Y--;
}
This is my result after collision checking and everything(It's a powdergame)

Printing Multiple Pages in a Winform application

I am attempting to print something using a C# Winforms application. I can't seem to understand how multiple pages works. Let's say I have the following code in my constructor:
private string _stringToPrint;
_stringToPrint = "";
for (int i = 0; i < 120; i++)
{
_stringToPrint = _stringToPrint + "Line " + i.ToString() + Environment.NewLine;
}
Then I have this code on my button click event:
private void MnuFilePrintClick(object sender, EventArgs e)
{
var pd = new PrintDocument();
pd.PrintPage += pd_PrintPage;
var z = new PrintPreviewDialog { Document = pd };
z.ShowDialog(this);
}
void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
var font = new Font("Arial", 10f, FontStyle.Regular);
g.DrawString(_stringToPrint, font, Brushes.Black, new PointF(10f, 10f));
}
Right now, when I run this code, it is giving me one page and after like 70 lines, it just runs off the paper. How would I print this string so that it prints enough for one page, then runs over to the second page, etc..?
You could have a counter and set the amount of lines you want per page like so:
private string[] _stringToPrint = new string[100]; // 100 is the amount of lines
private int counter = 0;
private int amtleft = _stringToPrint.Length;
private int amtperpage = 40; // The amount of lines per page
for (int i = 0; i < 120; i++)
{
_stringToPrint[i] ="Line " + i.ToString();
}
Then in pd_PrintPage:
void pd_PrintPage(object sender, PrintPageEventArgs e)
{
int currentamt = (amtleft > 40)?40:amtleft;
Graphics g = e.Graphics;
var font = new Font("Arial", 10f, FontStyle.Regular);
for(int x = counter; x < (currentamt+counter); x++)
{
g.DrawString(_stringToPrint[x], font, Brushes.Black, new PointF(10f, (float)x*10));
// x*10 is just so the lines are printed downwards and not on top of each other
// For example Line 2 would be printed below Line 1 etc
}
counter+=currentamt;
amtleft-=currentamt;
if(amtleft<0)
e.HasMorePages = true;
else
e.HasMorePages = false;
// If e.HasMorePages is set to true and the 'PrintPage' has finished, it will print another page, else it wont
}
I have had bad experiences with e.HasMorePages so this may not work.
Let me know if this works and I hope it helps!

Categories

Resources