Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PrintableArea in C# - Bug?

I am having an issue with PageSettings.PrintableArea's width and height values. Width, Height, and Size properties claim to "get or set" the values. Also, the inflate() function claims to change the size based on values passed in.

However, all of these attempts to change the value have not worked. Inflate() is ignore (no error, just passes as if it worked, but the values remain unchanged.

Attempting to set the height, width, or size gives a compiler error: "Cannot modify the return value of 'System.Drawing.Printing.PageSettings.PrintableArea' because it is not a variable".

I get the feeling that this means the "or set" part of the description is a lie.

Why I want to know this: (Someone always asks...) I have a printing application (C#, WinForm) that for most things is working rather well. I can set the printer settings and page settings objects to control what displays in the print dialog's printer properties. However, with Microsoft Office Document Image Writer, these settings are sometimes ignored, and the paper size returns as 0, 0 even when it displayed something else. All I really want it for it to be WYSIWYG as far as the displayed values go, so I change the paper size back to what it should be, but the printable area, if it is wrong, makes the resulting image wonky. The resulting image is the size of the printable area instead of the value in papersize. Just wondering if there was a reason for this or a way to get it not to do that.

Thanks in advance. :)

UPDATE:

  //ignored 
  PrintDocument.DefaultPageSettings.PrintableArea.Inflate(XOffset, YOffset);

 //causes compiler error
 PrintDocument.DefaultPageSettings.PrintableArea.Size = new SizeF((float)DimensionsPaperSize.Width, (float)DimensionsPaperSize.Height);
 PrintDocument.DefaultPageSettings.PrintableArea.Height = DimensionsPaperSize.Height;
 PrintDocument.DefaultPageSettings.PrintableArea.Width = DimensionsPaperSize.Width;

UPDATE 2:

For my (custom size) printers that print correctly, when I change the PaperSize, the PrintableArea and PageBounds change automatically to match it. When I change the PaperSize on MDIW, only the PageBounds change. I don't understand what's causing that.

CONCLUSION:

Nobugz has done a great job explaining why PrintableArea cannot be set (and would normally never need to be) and why its inflate() function is ignored, so I'm marking that as the answer.

As far as the persistent problem that prompted me to ask this question, I'm still at a loss. In response to the 'ScaleTranform' suggestion, the PaperSize and Graphics objects have correct values already, so messing with those values aren't likely to be of help. I suspect the most I could do along that route is resize my correctly-sized image to the garbage values I am getting for PrintableArea. I'm going to assume it is bug-related behaviour when explicitly setting PaperSize fails to modify the PrintableArea accordingly.

Its been frustrating that I seem to be the only person who has run into this problem. At least, so far I have only observed this behaviour for MODIW. For anyone's reference, and so there is as much information out there as possible; I am running 32-bit Win7, developing in VS2008. To replicate the problem are these steps:

PrintDialog PrintDlg = new PrintDialog();
PrintDocument PrintDoc = new PrintDocument();
PrintDoc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(DocumentPrintPage);
PrintDlg.PrinterSettings.PrinterName = printerName; //MODIW
PrintDoc = AlterPaperSize(PrintDoc); //A function that just changes the papersize
PrintDlg.Document = PrintDoc;
PrintDlg.PrinterSettings = PrintDoc.PrinterSettings;
if (PrintDlg.ShowDialog() == DialogResult.OK)
{
   if ((PrintDoc.DefaultPageSettings.PaperSize.Width == 0) &&
       (PrintDoc.DefaultPageSettings.PaperSize.Height == 0))
   {
      PrintDoc.DefaultPageSettings.PaperSize = DimensionsPaperSize;
   }
   PrintDoc.Print();
}
like image 458
Brandi Avatar asked Apr 07 '10 20:04

Brandi


3 Answers

This is a pretty fundamental issue with .NET programming, every programmer falls for it at least once. The PrintableArea property type is RectangleF. That's a structure, a value type. When you use the property, you get back a copy of the value.

The compiler will notice that you are trying to modify a member of the copy, like when you try to assign the Height property. But it gets noddy when you use the Inflate() method. You are inflating the copy, not the original value and the compiler isn't smart enough to notice.

Key problem here is that the PrintableArea property only has a getter, it doesn't have a setter. Which means that you can't change it. Which makes sense if you think about it, you can't change the size of the piece of paper nor change the design of the printer. You probably want to use the Margins property.

like image 199
Hans Passant Avatar answered Sep 29 '22 03:09

Hans Passant


Ok, I know this is a bit old, so appologies, but I had the same problem, and found out how to correctly set the paper sizes so that the PrintableArea is correct, as this was one of the few posts that came up when I 'googled' the problem I thought I'd add how I got it to work here, so the next person stumbling over this gets an answer.

When setting the PaperSize = New PaperSize(...) you are making up a custom size, even if you name it "A4" or "A5". Instead you need to set the paper size to one of the standard sizes held in PrinterSettings.PaperSizes.

Below is some C# .NET 3.5 code showing how I get the A4 and A5 sizes as variables which I can then use as appropriate, shown on the last line as I set the PaperSize, now the PrintableArea will be correct.

IEnumerable<PaperSize> paperSizes = settings.PaperSizes.Cast<PaperSize>();
PaperSize sizeA5 = paperSizes.First<PaperSize>(size => size.Kind == PaperKind.A5);
PaperSize sizeA4 = paperSizes.First<PaperSize>(size => size.Kind == PaperKind.A4);
settings.DefaultPageSettings.PaperSize = sizeA5; 
like image 26
Michael Ball Avatar answered Oct 01 '22 03:10

Michael Ball


I recently was able to figure this out for myself. When assigning a new paper size: A) you must specify "Custom" B) There are constraints on the paper sizes. I haven't figured them out, and they might be printer dependent. If you have an invalid size, the Printable Area becomes the default 8.5x11. It might be that they must be multiples of 10.

.DefaultPageSettings.PaperSize = New PaperSize("Custom", 1100, 2200)

does not work:

.DefaultPageSettings.PaperSize = New PaperSize("Custom", 1093, 2290)

Let me know if you find out anything more.

like image 32
Steve Avatar answered Oct 01 '22 03:10

Steve