WPF 与设备无关的单位
WPF从发布之日起,一直将“分辨率无关(resolution independence)”作为其亮点,声称使用WPF制作的用户界面在轻巧的Ultra-Mobile PC的屏幕上和在50英寸的电视机上都能很好地显示。微软之所以称WPF具备“分辨率无关”这一特性,主要是因为WPF的坐标单位设计成为以1/96英寸为一个逻辑像素单位,而不是与设备相关的像素单位。
但是微软本身对WPF“分辨率无关”这一特性没有作更多的具体解释,导致用户会产生很多误解。
误解之一
改变显示器的分辨率设置,同一个WPF的用户界面和绘制的图形尺寸不会变化。
这个可以用一个非常简单的实验证明该结论是错误的。新建一个WPF应用程序窗口,其中高度为400DIUs(DIU:Device independent unit,设备无关单位),宽度为600DIUs,让这个窗口分别在分辨率设置为1280 * 1024和800*600的环境下运行,如下图所示,两个窗口的尺寸是明显不一样的。
图 1 左图为1280 * 1024分辨率,右图为800*600分辨率
误解之二
改变显示的DPI设置,同一个WPF的用户界面和绘制的图形尺寸不会变化。
显示的DPI设置,在XP系统下是通过右键——属性——设置选项卡——高级,可以调用出来,如下图所示:
图 2 显示属性DPI设置
这个也可以用同样的方法进行证明该结论是错误的。仍然是高度为400DIUs[1],宽度为600DIUs的窗口分别运行在96DPI和192DPI两种设置环境下。从下图也可以明显看出窗口的尺寸是不一样的。
图 3 左图为96DPI,右图为192DPI
误解之三
在不同屏幕上,如果DPI设置相同,则同一个WPF的用户界面和绘制的图形尺寸不会变化。
在这个地方有必要对屏幕的DPI设置进行一下解释说明。DPI设置是指屏幕上每英寸多少个像素,比如当前设置为96DPI,即屏幕上96个像素为1英寸。一般的Windows XP系统有正常尺寸(96DPI)、大尺寸(120DPI)和自定义尺寸三种选项。既然WPF的坐标单位是以1/96英寸为一个逻辑像素单位,那么我们有理由相信,如果两个显示器的DPI设置是相同的,那么同一个WPF的用户界面和绘制的图形尺寸不会变化。很遗憾,这样的结论依旧是一个错误。
CalvinP.Schrotenboer 也用一个实验证明这是一个错误。实验环境如表 1,比如桌面LCD显示器实际屏幕宽度和高度(像素单位)为1600 x 1200,这个和普通的分辨率设置需要区分,这是显示设备的最大分辨率或者说是物理分辨率,即物理上该显示器屏幕上是1600 x 1200个像元,英文中又称这种分辨率为“native resolution(原生分辨率)”。由于两个屏幕物理尺寸也不一样,所以实际的物理DPI可以通过表中的计算公式得到。实际的物理DPI和操作系统的DPI设置是没有什么联系的。
表 1实验环境
实验环境 |
系统一 |
系统二 |
显示器类型 |
桌面LCD显示器 |
笔记本LCD显示器 |
屏幕宽度和高度 (像素单位) |
1600 x 1200 |
1400 x 1050 |
屏幕宽度和高度 (英寸单位) |
17.0 x 12.75 |
12.0 x 9.0 |
实际的物理DPI |
纵向:1600 / 17.0 = 94DPI 横向:1200 / 12.75 = 94DPI |
纵向:1400 / 12 = 117DPI 横向:1050 / 9 = 117DPI |
操作系统的DPI设置 |
96DPI |
96DPI |
在两个不同系统当中运行同一个WPF应用程序,该程序了绘制了一条长为384DIUs的直线,换算成英寸即为384/96= 4英寸。结果在两个系统当中的实际尺寸如下图所示:
图 4 上图实际尺寸为4.08英寸,下图实际尺寸为3.28英寸(CalvinP.Schrotenboer,2006)
问题出在哪儿了?
其实从表 1当中就能看出一些端倪,原因正是在于实际的物理DPI和操作系统设置的DPI不一致造成的。WPF无法知道当前使用设备实际的物理DPI为多少,相反通过操作系统的API函数获得操作系统的DPI值,然后简单地认为这就是实际的物理DPI值。比如在桌面LCD显示器上,实际一个物理像元的尺寸为1/94英寸,由于操作系统设置为96DPI,因此WPF还固执地以为一个实际的像元为1/96英寸,因此线段长度为1/94 * 384 = 4.08英寸。笔记本显示器实际一个物理像元的尺寸为1/117英寸,因此线段长度为1/117 * 384 = 3.28英寸。这个值和我们测量的结果正好相符。
那么我们有理由推测,如果将操作系统的DPI设置成实际的物理DPI,则能做到真正的“分辨率独立”,即在两个不同显示器上显示的线段长度都为4英寸,如图 5所示:
图 5 左图为桌面LCD显示器,将DPI设置成为94,右图为笔记本显示器,将DPI设置成为117
WPF的“分辨率无关”到现在为止已经是山高月小,水落石出。那么我们还要接着讨论另一个问题,在显示器上存在这样的问题,那么是否在打印机上也存在这样的问题呢?仍然可以用一个实验证明。同样绘制一个4英寸的直线,分别在DPI设置为96DPI和120DPI下进行打印,得到的打印结果尺寸相同。如下图所示:
图 6 左图为系统设置120DPI下打印结果,右图为系统设置96DPI下打印结果
结论
通过上面几个实验分析,我们可以得到如下两个结论:
(1) WPF在打印得时候可以做到“分辨率无关”,即同一个WPF用户界面和绘制的图形尺寸在任何一台打印机上输出都是一致的;
(2) 当显示器实际象元的物理尺寸和系统设置的DPI保持一致的时候,WPF可以在显示器上做到“分辨率无关”,即同一个WPF用户界面和绘制的图形尺寸在任何一台显示器(实际象元的物理尺寸和系统设置的DPI保持一致)上输出都是一致的。反之则无法保证。
更多的讨论
“分辨率无关”这样一个概念,由于微软本身讨论得不多,的确容易造成误解。最为详细地讨论了WPF当中“分辨率无关”的是CalvinP.Schrotenboer 的一篇博文“Is WPF Really Resolution Independent?”。当然Charles Peztold也在自己的博客当中讨论过这个问题。另外在微软的论坛上StephenW,Charles Peztold等人也就WPF的“分辨率无关”和“设备无关”作了比较深入的讨论。
用户固然可以不理睬这些,但是对于一个程序员来说,尤其是一个正在做绘图程序的程序员,尤其尤其是一个还需要打印输出的绘图程序员,是需要清楚这其中细节的。而且了解细节本身也是一件很愉快的事情。
参考文献
【1】 CalvinP.Schrotenboer(2006), Is WPF Really Resolution Independent? http://www.wpflearningexperience.com/?p=41
【2】 StephenW, Charles Peztold,etc(2007), Resolution Independence?, http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/33bdb15c-a04c-4c17-85e1-6c2802f80b90
转载自:http://www.cnblogs.com/helloj2ee/archive/2009/04/21/1440709.html
WPF 与设备无关的单位的更多相关文章
- 论wpf的设备无关性 - 简书
原文:论wpf的设备无关性 - 简书 WPF从发布之日起,一直将“分辨率无关(resolution independence)”作为其亮点,声称使用WPF制作的用户界面在轻巧的Ultra-Mobile ...
- 2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000ThingsYou Should Know About C# 和 2,00 ...
- WPF显示尺寸与设备无关问题
WPF单位 WPF窗口以及其中的所有元素都是用与设备无关的单位进行度量.一个与设备无关的单位被定义为1/96英寸.WPF程序统一用下面一个公式来定义物理单位尺寸: [ 物理单位尺寸(像素)] = [ ...
- 第15章 设备无关位图_15.1 DIB文件格式
15.1 DIB文件格式(一种文件格式,扩展名为BMP) 15.1.1 OS/2风格的DIB 文件格式 字段 说明 文件头 (BITMAPFILEHEADER) 1.共14个字节 2.缩写建议用bmf ...
- device-independent bitmap (DIB) 设备无关位图
设备无关位图即独立于设备的位图(DIB)与"Device-Dependent Bitmaps (DDB) 设备相关位图"相比,它不再依赖于具体的设备,从而更适合在不同的计算机之间传 ...
- 第15章 设备无关位图_15.3 DIB和DDB的结合
第15章 设备相关位图_15.3 DIB和DDB的结合 15.3.1 从DIB创建DDB (1)hBitmap =CreateDIBitmap(…)——注意这名称会误导,实际上创建的是DDB 参数 说 ...
- 【笨嘴拙舌WINDOWS】设备无关图(*.bmp)
设备无关图在windows上面就是一个扩展名为.bmp的文件.我们知道每一种文件都是一个二进制流,只是这个二进制流的开头几个字节是规定了文件的格式..bmp的文件格式如下 “其中信息头是windows ...
- 第15章 设备无关位图_15.2 显示和打印DIB
15.2.1 探究DIB (1)DIB文件的结构 整个文件 紧凑DIB(整个文件除文件头) 文件头(File Header) 信息头(Information Header) 信息头(Informati ...
- 为C1Chart for WPF添加自定义标题、坐标轴单位标签以及旋转坐标轴注释
对于图表控件C1Chart for WPF,我们在添加数据,选择图表类型这些基本可视化数据展示后,经常需要通过标题.坐标轴单位标签等信息辅助说明图表对实际场景的意义.C1Chart for WPF并没 ...
随机推荐
- Linux内核设计笔记7——中断
中断与中断处理 何为中断? 一种由设备发向处理器的电信号 中断不与处理器时钟同步,随时可以发生,内核随时可能因为中断到来而被打断. 每一个中断都有唯一一个数字标志,称之为中断线(IRQ) 异常是由软件 ...
- nodejs笔记--express篇(五)
创建一个express + ejs的项目 express -e testEjsWebApp cd testEjsWebApp npm install http://localhost:3000 Usa ...
- H5页面 绝对定位元素被 软键盘弹出时顶起
H5页面 绝对定位元素被 软键盘弹出时顶起 在h5页面开发的过程中,我们可能会遇到下面这个问题,当页面中有输入框的时候,系统自带的软盘会把按钮挤出原来的位置.那么我们该怎么解决呢?下面列出一下的方法: ...
- HDU 2115 I Love This Game
http://acm.hdu.edu.cn/showproblem.php?pid=2115 Problem Description Do you like playing basketball ? ...
- [C/C++] C/C++错题集
1. 解析: A:在GCC下输出:0 在VC6.0下输出:1 B:在GCC下输出:段错误 (核心已转储) 在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作. C:正常 ...
- 请问:在delphi中怎样判断DBgrid中数据是否被修改,以便在退出窗口时加以提示
若DBGrid.DataSource.DateSet为ADOQuery1,这样试一下:if ADOQuery1.Modified then ... procedure TForm1.FormClose ...
- 移动端body跟着模态框一起滑动问题
遇到了一个问题,是点击链接出现弹框,弹框里面的内容是可以滑动的,结果我滑动的时候发现下面的body也跟着一起滑动,先看一下代码. 弹框的 HTML: <div class="mask& ...
- 【bzoj4921】[Lydsy六月月赛]互质序列 暴力
题目描述 给出一个序列,要求删除一段非空区间,使得剩下的数的个数大于等于2.求所有删除方式剩下的数的最大公约数的和. 输入 第一行包含一个正整数n(3<=n<=100000),表示序列的长 ...
- [NOIP2016]愤怒的小鸟 状态压缩dp
题目描述 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形 ...
- JS变量对象详解
JS变量对象详解 开年之后工作热情一直不是很高,这几天一直处于消极怠工状态.早上不想起床,起床了不想上班.明明放假之前工作热情还一直很高,一直心心念念的想把小程序项目怼出来,结果休假回来之后画风完全不 ...