Print Fit To Page - c#

I need to print a label to fit the page.
I'm tryng this but print big than page, width and height seems to be to much
private void PrinterPrintPage(object sender, PrintPageEventArgs e)
{
var b = Tasks.Pop();
if (b.Label == null)
b.Label = GetLabelImage(b.Codice, b.ColoreID);
var rect = e.PageBounds;
e.Graphics.DrawImage(b.Label, rect);
e.HasMorePages = Tasks.ContainTasks();
_printedCount++;
}

As per MSDNs documentation on PrintPageEventArgs.PageBounds,
Most printers cannot print at the very edge of the page.
...first of all, try changing PageBounds to MarginBounds. If this doesn't help, "deflate" the bounds rectangle towards the centre of the page so you move away from the edges.

Related

Grow picturebox to top direction

Is it possible to give a picturebox a new size but instead of it growing down and right i want it to grow up and right. So basicaly I want the left bottom corner to be locked in the same position all the time.
As you can see in the image i want the green box to be above the line.
I have tried to make a formula to calculate the new position but cant figure out how to write it.
If you're assigning size at runtime, for example:
private void button1_Click(object sender, EventArgs e)
{
this.pictureBox1.Size = new Size( 200, 200 );
}
then just handle the PictureBox Resize event:
private void pictureBox1_Resize(object sender, EventArgs e)
{
var padding = 12; //Forms designer snap-to padding.
var titleBarHeight = 41;
this.pictureBox1.Location = new Point(padding, this.Height - this.pictureBox1.Height - titleBarHeight - padding);
}
This will handle the size assignment, as well as if you've anchored the PictureBox and are resizing the form.
If you're just resizing at design time, then just anchor the PictureBox:
It'll resize where ever it's sitting on the form. As mentioned above, it'll also work automatically for form resize at run time.

Add watermark below image but within print area in C#

I am trying to insert a text watermark underneath a TIFF image in my windows form and would definitely appreciate anyone's help. I have a print button that retrieves the image, scales it down, then based on my margins, places the image accordingly to print. I'd like to add an additional piece where just before the image prints, I add in a text watermark (in this case a date stamp) that is just below the image.
I've tried adjusting the margin but that just increases (or decreases depending on the number setting) the image scale but does not add the additional room I want to add the watermark. Below is code of what I have so far:
protected void PrintPage(object sender, PrintPageEventArgs e)
{
if (this.Image == null)
{
e.Cancel = true;
return;
}
//ADD TIME STAMP WATERMARK
string watermark = "DATE ISSUED: " + String.Format("{0:MM/dd/yyyy}", System.DateTime.Now.Date);
System.Drawing.Graphics gpr = Graphics.FromImage(Image);
System.Drawing.Brush brush = new SolidBrush(System.Drawing.Color.Black);
Font font = new System.Drawing.Font("Arial", 55, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
SizeF size = e.Graphics.MeasureString(watermark, font);
float x = 0;
float y = Image.Height-size.Height;
RectangleF printArea = new RectangleF(x, y, size.Width, size.Height);
gpr.DrawString(watermark, font, brush, printArea);
e.Graphics.DrawImage(this.Image, e.MarginBounds);
}
The value of e.MarginBounds I have set in my App.config and include the following values: Left=70, Right=90, Top=190; Bottom=475. All the printouts are going to be printed portrait style on Letter 8 1/2 by 11 size paper.
I am able to display the watermark anywhere on top of the image, but I am hoping to place it underneath. When I adjust the y coordinate, and it so happens to be below the image, when I print, I assume that it is outside the print area and therefore, the watermark does not get printed on the page (it only shows the image).
I appreciate anyone's help in this as I have been racking my brain on this and have had no luck.
Aren't you printing your text beneath the image. I think you want to start printing at y=Image.Height + e.MarginBounds.Top, and x=e.MarginBounds.Left
That will print a your label left justified below the image in the margin.
Update: This works:
y=-size.Height + e.MarginBounds.Bottom;
x = e.MarginBounds.Left;
e.Graphics.DrawImage(Image, e.MarginBounds);
// note the change. Using e.graphics instead of gpr below
e.Graphics.DrawString(watermark, font, brush, printArea);

PrintDocument always has margin

I am having a problem when using PrintDocument with margins.
No matter what I do there is always a margin around everything I print, this means that nothing is aligned where it needs to be.
Here is the code I am using to create the PrintDocument
public void Print()
{
PrintDocument printDocument = new PrintDocument();
printDocument.DefaultPageSettings.PaperSize = new PaperSize("A5",583,827);
printDocument.OriginAtMargins = true;
printDocument.DefaultPageSettings.Margins.Top = 0;
printDocument.DefaultPageSettings.Margins.Left = 0;
printDocument.DefaultPageSettings.Margins.Right = 0;
printDocument.DefaultPageSettings.Margins.Bottom = 0;
if (!string.IsNullOrWhiteSpace(PrinterName))
{
printDocument.PrinterSettings.PrinterName = PrinterName;
}
printDocument.PrintController = new StandardPrintController();
printDocument.PrintPage += On_PrintPage;
printDocument.Print();
}
The On_PrintPage method, has various calls to e.Graphics.Draw... methods.
How can I make it so that something I print at 0,0 will print in the very top left of the page. I know that if the printer cannot print that far to the edge of the page it will be blank, however it should do that rather than print 0,0 not in the top left of the page.
I'm really lost here
interestingly the print function is too late to set most of the properties and would only apply to subsequent pages
you need to use PrintDocument.QueryPageSettings event instead and set the properties there and I always set the page settings not just defaults. then drawing at 0,0 should be as close as you can get (printer + driver allows)
The OriginAtMargins property of the PrintDocument, when set to true, it will sets the origin of the provided Graphics object at the top-left corner of the margin. From the MSDN document Remarks section:
Calculating the area available to print requires knowing the physical
size of the paper, the margins for the page, and the location of the
Graphics object origin. When OriginAtMargins is true, the Graphics
object location takes into account the PageSettings.Margins property
value and the printable area of the page. When OriginAtMargins is
false, only the printable area of the page is used to determine the
location of the Graphics object origin, the PageSettings.Margins value
is ignored.
Set it to false, to change it to the top-left corner of the printable area. If you need it to be at the top-left corner of the page, you will need to transform the graphics object to mach that coordinate; there isn't really a way to get around this:
void PrintDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
var printArea = e.PageSettings.PrintableArea;
e.Graphics.TranslateTransform(-printArea.X, -printArea.Y);
// Build up the page here.
}
If you want to print landscape pages as well, this becomes tricky, as none of the properties of PageSettings are affected by this setting. This requires to know the angle the page is rotated by—as PrintableArea isn't always centered on the page—which can be acquired with PageSettings.PrinterSettings.LandscapeAngle. The value can only be either 90 or 270, and the code would look like this:
void PrintDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
var printArea = e.PageSettings.PrintableArea;
if (e.PageSettings.Landscape)
{
var pageSize = e.PageSettings.PageSize;
switch (e.PageSettings.PrinterSettings.LandscapeAngle)
{
case 90:
e.Graphics.TranslateTransform(
dx: -printArea.Y,
dy: -(pageSize.Width - (printArea.X + printArea.Width)));
break;
case 270:
e.Graphics.TranslateTransform(
dx: -(pageSize.Height - (printArea.Y + printArea.Height)),
dy: -printArea.X);
break;
}
}
else
{
e.Graphics.TranslateTransform(-printArea.X, -printArea.Y);
}
// Build up the page here.
}
If you later want to use another transformation on a portion of the page, do not forget to use var gs = e.Save() before transforming and e.Restore(gs) to restore that transformation, instead of calling e.ResetTransform(), as the later will reset the transformation you did in the beginning.

Winform Textbox on top of image not printing

I have a Winform application that creates signs. Everything works and looks fine except when I print. I have an image with textboxes placed on top of them. They are visible on my computer, but not when I print. I am assuming that somehow when I print the image is getting "Brought-to-front."
Below is my Print Function:
private void btnPrint_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(PrintImage);
pd.Print();
}
void PrintImage(object o, PrintPageEventArgs e)
{
int x = SystemInformation.WorkingArea.X;
int y = SystemInformation.WorkingArea.Y;
int width = this.Width;
int height = this.Height;
Rectangle bounds = new Rectangle(x, y, width, height);
Bitmap img = new Bitmap(width, height);
this.DrawToBitmap(img, bounds);
Point p = new Point(100, 100);
e.Graphics.DrawImage(img, p);
}
I don't know for sure that anything in the print function is a cause, but I can't think of anything else.
I don't know the answer to the question of why the TextBox contents are not being rendered, but I can tell you that you are doing it "wrong".
What you should be doing is rendering the text in your paint handler and using a single, "in-place" TextBox for allowing the user to edit text at some location on the form which is moved into position and made visible just-in-time for editing.
It requires that your "document" consist of lists of objects (like "text blocks") which you can render and which you can detect the bounds of for when the user tries to manipulate them. This is very similar to how a "paint" program works.
This is going to be a complete departure from what you are doing now. It's always a lot more work to do things "correctly". I don't want to tell you to redo your application. If this is a learning experience and not a commercial product, it's OK to hack your way through it, using what you're familiar with. But maybe next time you might try another approach.

Printing graphics on multiple pages using System.Drawing.Printing, based on the used coordinates in C#

Using System.Drawing.Printing, I want to print a set of lines on print document.
But the problem is it prints every line on the very first page, what ever the coordinates are, also if I draw an image, It prints that on a single page no matter how big it is.
Following is what I have done for printing text on multiple pages:
protected void ThePrintDocument_PrintPage (object sender, System.Drawing.Printing.PrintPageEventArgs ev)
{
float linesPerPage = 0;
float yPosition = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
string line = null;
Font printFont = this.richTextBox1.Font;
SolidBrush myBrush = new SolidBrush(Color.Black);
// Work out the number of lines per page, using the MarginBounds.
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics);
// Iterate over the string using the StringReader, printing each line.
while(count < linesPerPage && ((line=myReader.ReadLine()) != null))
{
// calculate the next line position based on
// the height of the font according to the printing device
yPosition = topMargin + (count * printFont.GetHeight(ev.Graphics));
// draw the next line in the rich edit control
ev.Graphics.DrawString(line, printFont, myBrush, leftMargin, yPosition, new StringFormat());
count++;
}
// If there are more lines, print another page.
if(line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
myBrush.Dispose();
}
What I should do in order to print line on multiple pages, i.e the following code should print on two pages as the length of the line is 1400 and print doc length is 1100, so remaining 300 of the line should be printed on the next page
protected void ThePrintDocument_PrintPage (object sender, System.Drawing.Printing.PrintPageEventArgs ev)
{
Pen P1 = new Pen(Brushes.Violet, 5);
ev.Graphics.DrawLine(P1, new Point(0,0), new Point(500,1400));
}
This is not how printing works in .NET. It does not create a new page just because you print outside the coordinates of the current page. There are events and event arguments which .NET uses to ask from you how many pages your document will contain. It will then invoke the event for printing a page for every page.
See here for an example.
EDIT
Ok, replying to your comment, I can think of two possible solutions: The first solution would involve clipping: intersect your graphic objects with the page's rectangle and print only what's common to both of them. If there were parts outside the clipping region, take that part as the new graphic objects and clip again to print on new page. Repeat this until the remaining graphics fit the page rectangle. However, I can't think of a way of doing that easily.
My second idea is as follows:
Calculate how many pages you would need to print all graphic objects by dividing the bounding rectangle of the graphic objects by the height of the "visual rectangle" of one page (increase number of pages by one if there's a remainder in this division).
Loop the following until reaching the last page
Print all graphic objects to the current page
Decrease all y-coordinates by the "visual height" of a page (effectively moving the graphic objects upwards outside the "bounds of the paper")
While the overhead of printing the entire list of graphic objects for every page may be high, you're leaving the clipping part to the printer driver/the printer itself.

Categories

Resources