C# 中的 PrintableArea - Bug?
我对 PageSettings.PrintableArea 的宽度和高度值有疑问。 Width、Height 和 Size 属性声称可以“获取或设置”这些值。此外,inflate() 函数声称会根据传入的值更改大小。
但是,所有这些更改值的尝试都没有奏效。 Inflate() 被忽略(没有错误,只是像它工作一样传递,但值保持不变。
尝试设置高度、宽度或大小会出现编译器错误:“无法修改 'System.Drawing.Printing 的返回值” .PageSettings.PrintableArea'因为它不是变量”。
我感觉这意味着描述的“或设置”部分是谎言。
为什么我想知道这一点:(总是有人问...)我有打印应用程序(C#、WinForm)在大多数情况下都运行得很好,我可以设置打印机设置和页面设置对象来控制打印对话框的打印机属性中显示的内容,但是,使用 Microsoft Office Document Image Writer,这些设置是无效的。有时会被忽略,即使显示其他内容,纸张大小也会返回为 0, 0 我真的希望它能显示的值是所见即所得,所以我将纸张大小更改回应有的大小,但如果可打印区域错误,则会导致生成的图像不稳定。生成的图像是可打印区域的大小,而不是 papersize 中的值。只是想知道是否有原因或有办法让它不这样做。
提前致谢。 :)
更新:
//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;
更新 2:
对于正确打印的(自定义尺寸)打印机,当我更改 PaperSize 时,PrintableArea 和 PageBounds 会自动更改以匹配它。当我更改 MDIW 上的 PaperSize 时,只有 PageBounds 发生变化。我不明白是什么原因造成的。
结论:
Nobugz 很好地解释了为什么 PrintableArea 不能被设置(并且通常不需要设置)以及为什么它的 inflate() 函数被忽略,所以我将其标记为答案。
至于促使我提出这个问题的持续存在的问题,我仍然不知所措。为了响应“ScaleTranform”建议,PaperSize 和 Graphics 对象已经具有正确的值,因此弄乱这些值不太可能有帮助。我怀疑沿着这条路线我能做的最多的事情就是将正确大小的图像调整为我为 PrintableArea 获得的垃圾值。当显式设置 PaperSize 无法相应修改 PrintableArea 时,我将假设这是与错误相关的行为。
令人沮丧的是,我似乎是唯一遇到这个问题的人。至少,到目前为止我只观察到 MODIW 的这种行为。供任何人参考,因此有尽可能多的信息;我运行的是32位Win7,在VS2008中开发。要复制该问题,请执行以下步骤:
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();
}
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 .NET 编程的一个非常基本的问题,每个程序员至少都会遇到一次。 PrintableArea 属性类型是 RectangleF。这是一种结构,一种值类型。当您使用该属性时,您将获得该值的副本。
编译器会注意到您正在尝试修改副本的成员,例如当您尝试分配 Height 属性时。但是当您使用 Inflate() 方法时,它会变得很奇怪。您正在夸大副本,而不是原始值,并且编译器不够聪明,无法注意到。
这里的关键问题是 PrintableArea 属性只有一个 getter,没有 setter。这意味着您无法更改它。如果您考虑一下,这是有道理的,您无法更改纸张的尺寸,也无法更改打印机的设计。您可能想使用 Margins 属性。
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.
好吧,我知道这有点旧了,所以抱歉,但我遇到了同样的问题,并找到了如何正确设置纸张尺寸以使 PrintableArea 正确,因为这是我时出现的少数帖子之一“谷歌搜索”这个问题,我想我应该添加如何让它在这里工作,这样下一个遇到这个问题的人就会得到答案。
当设置 PaperSize = New PaperSize(...) 时,您正在创建自定义尺寸,即使您将其命名为“A4”或“A5”。相反,您需要将纸张尺寸设置为 PrinterSettings.PaperSizes 中保存的标准尺寸之一。
下面是一些 C# .NET 3.5 代码,显示了如何获取 A4 和 A5 尺寸作为变量,然后可以根据需要使用这些变量,如我设置 PaperSize 时的最后一行所示,现在 PrintableArea 将是正确的。
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.
我最近能够自己解决这个问题。
分配新纸张尺寸时:
A) 您必须指定“自定义”
B) 纸张尺寸有限制。我还没有弄清楚它们,它们可能依赖于打印机。如果尺寸无效,可打印区域将变为默认的 8.5x11。它们可能必须是 10 的倍数。
不起作用:
如果您发现更多信息,请告诉我。
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.
does not work:
Let me know if you find out anything more.