1.启用页边距:

默认情况下PrintDocument是不理会页边距的(MS再次让人无语。。。),这也是为什么有人说明明设了页边距在打印预览里却没有效果的原因。
解决办法是设置PrintDocument对象的OriginAtMargins属性为True,如下:

printDocument1.OriginAtMargins = true; //启用页边距

再来看一下从元数据中提取的关于OriginAtMargins属性的定义:


//

// 摘要:

//     获取或设置一个值,该值指示与页关联的图形对象的位置是位于用户指定边距内,还是位于该页可打印区域的左上角。

//

// 返回结果:

//     如果图形起始于页面边距,则为 true;如果图形原点位于该页可打印区域的左上角,则为 false。默认为 false。

[DefaultValue(false)]

public bool OriginAtMargins { get; set; }

可以看到此属性的DefaultValue为false,所以如果不改的话,页边距设的再大也没有用。

 2.PageSetupDialog中页边距的正常显示

这个问题一度搞得我有点儿心烦——每打开一次“页面设置”对话框,哪怕你不做任何更改就点“确定”关闭它,当你再打开它时你会发现,上面显示的页边距“神奇地”变小了。。。
举个具体的例子来说,如果你没有编程预设置页边距的话,默认第一次打开“页面设置”时的页边距应该是10mm,当你点“确定”关闭它再打开后,页边距变成了3.9mm,再重复这一操作,页边距又变成了1.5mm,依此类推。

之所以会出现不正常的现象,都是因为制式转换导致的——

.NET对于页边距是绝对的“大国沙文主义”,只认美制的“英寸”不认别的制式,其默认单位是“0.01英寸”。
而我们的OS就比较入乡随俗,知道用“毫米”。所以在PageSetupDialog窗体上中显示的单位是“毫米”(取决于OS)。
由于两边制式不一样,搭不上话,.NET就会强制的把OS的制式单位给转换成它“习惯”的“英寸”。 也就是说:
在你点击“页面设置”对话框的“确定”按钮后,.NET会自动进行“毫米->英寸”的隐式转换。
本来这也没什么大不了,问题出现在:

再度打开PageSetupDialog对话框时,PageSetupDialog对象却并没有进行与上面的隐式转换对应的“英寸->毫米”逆向转换,
而仅仅是简单粗暴地将单位名改了,从“Display”(0.01英寸)改成了“TenthsOfAMillimeter”(0.1毫米),数值却动都没动一下。
也就是说不管你给PageSetupDialog什么值,它都认为是以0.1毫米为单位的数。

看下面流程就明白了:


示10(mm)-->0.3937(in)-->39.97(0.01in)-->因为Margin尺寸只接受int
型,so-->39(0.01in) -->错误转换,只改单位-->39(0.1mm)-->显示3.9(mm)

问题是清楚了,怎么解决呢?

第一个办法(不是办法的办法):更改OS度量衡设置

操作系统是根据安装时选择的地区来确定不同的默认度量衡制式。我国用的度量衡系统是“公制”(米/厘米/毫米),而MS所在的美国用的是“美制”(英尺
/英寸)。在XP系统下,可以通过“控制面板”->“区域和语言选项”->“区域选项”->“标准和格式”->“自定
义”->“数字”->“度量衡系统”来设置当前的度量衡制式。把度量衡系统由“公制”改成“美国”,再去试验一切OK,只不过页边距后面括号
里的单位描述变成了“英寸”。OK的原因很简单,不需要转换了嘛。

第二个办法:编写代码将英寸正确的转换到毫米

我们可以利用.NET提供的PrinterUnitConvert类的Convert方法来实现这个目标,代码如下:


private void btnPageSetup_Click(object sender, EventArgs e)

{

    PageSetupDialog psd = new PageSetupDialog();

    psd.Document = printDocument1;

    Margins mg = printDocument1.DefaultPageSettings.Margins; //保存原始Margins

    psd.PageSettings.Margins = PrinterUnitConvert.Convert(mg, PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter);

    if (psd.ShowDialog() == DialogResult.Cancel)

    {

        //psd.PageSettings.Margins改变导致printDocument1.DefaultPageSettings.Margins也随之改变,

        //所以为了避免点了Cancel后,下一次打开对话框时mg被错误地赋给了已经改变了的printDocument1.DefaultPageSettings.Margins值,

        //需要将printDocument1.DefaultPageSettings.Margins还原。

        printDocument1.DefaultPageSettings.Margins = mg; 

    }

}

Convert方法的第三个参数必须为PrintUnit枚举中的TenthsOfAMillimeter(0.1毫米),只有这样才能与“错误转换”后的单位一致从而显示出正确的值。
如果上面把第三个参数换成PrinterUnit.HundredthsOfAMillimeter(0.01毫米),得到的数字要比0.1毫米的大10
倍,而PageSetupDialog不管你得到的数字是多少,都会认为它是0.1毫米单位的,所以显示出的页边距就会大10倍从而出错。

第三个办法:利用.NET 2.0新增的属性

.Net 2.0中,PageSetupDialog对象新增加了一个EnableMetric属性,MSDN中的描述是:

“获取或设置一个值,该值指示以毫米为单位显示边距设置时,是否自动将边距设置转换为以百分之一英寸为单位(或相反)。
……
PageSettings 类以百分之一英寸为单位测量 PageSettings.Margins,但 PageSetupDialog 允许用户以英寸或毫米为单位设置边距,具体取决于运行该应用程序的系统的区域设置。

.NET Framework 2.0 版中,如果您的应用程序可能会在以毫米为单位测量文档边距的区域中使用,则应将此属性设置为
true。如果要自己执行转换(像 .NET Framework 2.0 版之前的版本所要求的那样),则应使用默认值 false。”

此法最简单,只要设置EnableMetric为True即可。代码如下:


private void btnPageSetup_Click(object sender, EventArgs e)

{

    PageSetupDialog psd = new PageSetupDialog();

    psd.Document = printDocument1;

    psd.EnableMetric = true; //就是这句

    psd.ShowDialog();

}

WinForm打印之页边距的更多相关文章

  1. [办公应用]如何设置IE打印时的默认页边距,并设置纸张为横向(会计票据打印)

    最近一个做会计的同事询问,如何将IE打印时的默认页边距更改,并且每次都要是横向的纸张. 这是因为她已经测试好纸张的大小,并据此调整好了页边距.可惜的是下一次打印时,又要重新调整一遍. 经过研究,方法如 ...

  2. RDLC打印或导出Word的 分页设置 页边距和页面大小

    RDLC 导出Word的时候发现,Word的尺寸和页边距有问题,查了MSDN看到这样一段话 Page Sizing When the report is rendered, the Word page ...

  3. WinForm打印

    WinForm打印要用打印控件: PageSetupDialog:打印设置对话框 PrintDialog:打印对话框 PrintDocument:要打印的对象,非常重要 PrintPreviewCon ...

  4. [Q]打印机页边距设置

    问题描述:当您在使用CAD批量打图精灵默认设置打印图纸(使用pdfFactory虚拟打印机),可能会发现打印出的图纸页边距比您手工打印(使用Adobe或系统打印机)的要偏大. Adobe虚拟打印机打印 ...

  5. 从BIRT报表文件中获取页面设置信息(页边距、纸张大小、输出方向)的方法

     从BIRT报表文件中获取页面设置信息(页边距.纸张大小.输出方向)的方法    报表打印时,尤其是套打的报表,页面设置信息非常重要,比如页边距,纸张大小,输出方向等,而且每个报表的相关参数有可能不同 ...

  6. .Net(c#)打印--多页打印

    如果要实现多页打印,就要使用PrintPageEventArgs类的HasMorePages属性. 我们对之前的代码作如下变更:      增加PrintDocument的BeginPrint和End ...

  7. 【转】C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  8. C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  9. [办公应用]如何打印较小边距的PPT讲义(或者每页打印16页)

    关键词:打印 PPT 讲义 4张 边距   今天同事问我如何打印PowerPoint的讲义.她自己使用PowerPoint打印讲义,设置每页4张,但是页边距太大:觉得浪费很大. 经过网上查阅后,现将方 ...

随机推荐

  1. Mysql表操作

    查看表结构: 可以使用describe或show create table语句查看表的结构: describe表名; Show create table 表名; 修改表名: Alter table 旧 ...

  2. .NET高端职位招聘要求

    系统架构师: 1.硕士及以上学历,博士有项目成果者优先: 2.五年以上工作经验,三年以上互联网经验,一年以上大型软件项目总体设计.分析.架构经验,有移动互联网或云计算虚拟化系统设计开发经验者优先: 3 ...

  3. Android开发系列之Android项目的目录结构

    今天开始正式学习Android开发的种种细节,首先从最基本的概念和操作学起. 首先看一下Android项目的目录结构. 这是我随便建立的一个test项目,我们重点关注一下几个方面的内容: 1.src目 ...

  4. web api写api接口时返回

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...

  5. JQuery 事件器的介绍

    基本用法 $(元素). 事件( 事件属性); 常见事件 示例 说明 $(selector).click()  被选元素的点击事件 $(selector).dblclick()  被选元素的双击事件 $ ...

  6. SQL函数说明大全 (转)

    一旦成功地从表中检索出数据,就需要进一步操纵这些数据,以获得有用或有意义的结果.这些要求包括:执行计算与数学运算.转换数据.解析数值.组合值和聚合一个范围内的值等. 下表给出了T-SQL函数的类别和描 ...

  7. 开发设计模式(二) ActiveObject模式

    ActiveObject模式: ActiveObject模式和Command模式的配合使用是实现多线程控制的一项古老的技术,该模式有多种使用方式,为许多工业系统提供了一个简单的多任务核心. // 活动 ...

  8. .net faq

    http://www.indiabix.com/technical/dotnet/ http://www.codeproject.com/Articles/637480/Csharp-and-ASP- ...

  9. Swagger+AutoRest

    Swagger+AutoRest 生成web api客户端(.Net)   简介 对于.net来说,用web api来构建服务是一个不错的选择,都是http请求,调用简单,但是如果真的要在程序中调用, ...

  10. 使用WampServer 3.0

    在server上安装了WampServer 发现本地使用良好,但是无法从别的PC访问. 原因有二: 1.现象:输入连接无反应 原因:server本身用了80端口,所有WampServer我就设置了80 ...