views:

411

answers:

2

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();
}
+4  A: 

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.

Hans Passant
man, that sounds good, but the whole "the compiler isnt smart enough to notice" thing could probably use some clarification. How does the compiler not notice the diff between two value types?
Mike_G
@Mike: well, it doesn't generate an error when you use the Inflate() method on the property. The copy gets inflated, but then doesn't get assigned to anything. Which is technically valid, the Inflate method might have useful side-effects. Although it doesn't. The compiler doesn't know that it doesn't have useful side-effects.
Hans Passant
I see... guess I'm out of luck then as I haven't noticed that the margins make any difference in the end product. Thank you for the detailed answer.
Brandi
@Brandi, PaperSize is also involved, and you are changing the _default_ settings. May have to look at the actual settings.
Henk Holterman
@Henk, I can't find any actual settings object... as far as I can tell PrintDocument.DefaultPageSettings are the settings used? If you have a reference or some code, I would love to see.
Brandi
Use the Graphics.ScaleTransform and TranslateTransform methods in the PrintPage event to move and scale what you print on paper.
Hans Passant
A: 

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.

ex. works: .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.

Steve