WPF显示尺寸与设备无关问题

WPF单位

  • WPF窗口以及其中的所有元素都是用与设备无关的单位进行度量。一个与设备无关的单位被定义为1/96英寸。WPF程序统一用下面一个公式来定义物理单位尺寸:

    
    
    [ 物理单位尺寸(像素)] = [ 设备无关尺寸 ]*[ 系统DPI ]
    
    
  • 我们知道标准的Windows的系统DPI是 96 dpi,这个时候物理单位就是1像素,一个40*40WPF单位的按钮,就是一个40*40像素的按钮。 但是本质上WPF的显示与显示设备有关,WPF的与设备无关的特性并不是说把WPF放到哪一个设备上显示尺寸都是一样的。

屏幕DPI与系统DPI

  • 屏幕DPI的计算公式是:

    
    
    [屏幕DPI(DPI)] = sqrt(HeightPixel^2 + WidthPixel^2) / screenDiagonalLength
    
    
  • 比如一部14英寸(14英寸是笔记本的屏幕对角线长度),1920*1080像素大小的分辨率(高分屏),得出来的屏幕分辨率为157.351(四舍五入157)。比windows系统默认的DPI要高。如果在这样的电脑屏幕上显示信息,相当于用157个像素构建一个英寸,比默认情况下96个像素构建一个英寸,在像素密度的上大得多,这就是高分屏为什么比普通的屏幕显示要更加精细和清晰的原因了,但是这样会带来另一个问题,比如桌面的图标,会随着分辨率的提高而不断缩小,有一些软件字体和界面变得超级小的问题。

  • 如果通过改变分辨率来让显示变大,是不太好的(液晶显示屏使用固定的像素点来显示图像的),比如如果降低分辨率,就会造成迫使显示器使用1.2个点来显示显卡的一个像素点,这个时候显示器会使用插值的方法来填充像素点,从而造成模糊。 我们可以通过改变DPI来改善显示,但是同样会导致显示模糊的问题,因为当改变DPI时,很有可能让需要显示的像素出现小数(比如一个32*32像素的图标变成了46.8*46.8的图标,但是屏幕显示都是整数,就会引发插值导致模糊)(比如WIN10强制缩放应用程序,让很多老的而程序直接显示模糊,包括Windows自己的那一堆msc程序)
  • 由于WPF使用设备无关单位来刻画程序,所以WPF是支持系统DPI设置的,比如要显示一个96*96像素的一个图标,如果系统DPI为120dpi,那么根据WPF程序定义物理单位尺寸的公式,那么一个物理单位尺寸为1.25像素:

    
    
    [ 物理单位尺寸(像素)] = 1/96*120 = 1.25
    
    
  • 这样一来我们要显示的图标大小为120个像素,随着系统DPI变大而变大了。

当且仅当系统DPI和屏幕DPI相等时,WPF程序的显示尺寸才是与显示设备无关

  • 就像上面我们说的,仿佛WPF程序无论是在哪个显示设备上显示的尺寸都是一样的,微软在WPF与设备无关的问题上也没有过多的解释。但实际上,在打印输出上,WPF确实可以做到在任何一台打印机上,图形尺寸都是一样的;但是在显示器上,系统DPI一定要和屏幕DPI相等时,输出才一致。并不是说在任何屏幕,任何分辨率下输出都是一样:

  • 比如在一个14寸1920*1680分辨率的屏幕下(屏幕DPI为157(取整)),和1366*768分辨率下(屏幕DPI为112(取整))下,只有当系统DPI设置为各自的屏幕DPI时,显示长度才是一样的:(偷懒一下直接把96dpi看成100dpi了)

图1:1902*1080分辨率,系统DPI为96*157%,长度大概是10.1cm

图2:1366*768分辨率,系统DPI为96*112%,长度大概是10.2cm

  长度大概相等,如果系统DPI不等于屏幕DPI,程序大小还是会改变的。WPF并不能真正做显示与所有设备无关。

 

  参考:WPF单位真的与分辨率无关吗? -By helloj2ee  

        :《WPF编程宝典 -使用C# 2012和.NET4.5 (第四版)》

原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/6344863.html