【WPF】SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考

简介: 原文:【WPF】SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考 MSDN上解释了一大堆,二者对比来看,并不能发现什么明显的区别,微软爸爸也不知道多给写图文实例。
原文: 【WPF】SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考

MSDN上解释了一大堆,二者对比来看,并不能发现什么明显的区别,微软爸爸也不知道多给写图文实例。经过几个小时的摸索,现得到以下共同点和不同点,仅供参考:

共同点

  1. 默认值都是false,如果设置到root元素上,则child元素也自动使用同样设置。
  2. 都是为了解决wpf元素边缘模糊的问题(如下)。

wpf界面元素呈现时为了看起来更平滑一点,是有抗锯齿效果的,抗锯齿效果就会导致边缘模糊。举个例子来说,边缘是如何模糊的:
这里写图片描述
假如你有条横线,在界面上show的时候应该正好摆放在上下两个像素点的中间地带,如上图所示。wpf在呈现这条线时,会把上下两边的像素点同时着色(同样适用于左右两边)。到底着的是什么颜色,wpf会根据自己的一套算法之类的东西计算出来。这样就会导致整体看起来跟自己想要的相比,会有点透明度,也会看起来模糊了。
为了解决这个问题,就出现了SnapsToDevicePixels 和UseLayoutRounding,不过UseLayoutRounding是.net 4.0之后的产物,微软也建议在程序中优先使用UseLayoutRounding。二者的默认值都是false。在上图的那个问题中,不管是设置UseLayoutRounding=true还是SnapsToDevicePixels =true,都会解决模糊的问题。貌似没什么区别。
详见微软给出的模糊不清的例子:
1.FrameworkElement.UseLayoutRounding 属性
2.Pixel Snapping in WPF Applications
其实可见二者区别不大,给出的例子都只是换了换文字:

这里写图片描述

不同点

  1. 二者最大的不同点,其实MSDN上已经讲了:UseLayoutRounding是在during layout的时候生效的,而SnapsToDevicePixels是在during rendering的时候生效的

当layout已经呈现完毕,用UseLayoutRounding所修饰元素的像素对齐样式都已经固定,不依元素位置的变动而动态调整。而SnapsToDevicePixels因为是在render的时候生效的,所以它所修饰的元素 的位置如果发生改变的话,它的像素对齐样式是会改变的。可见下图:
这里写图片描述

这里是5个close的小图标,width和height设置的都是14,原图是72x72像素的,用放大镜放大到600%。
1号:SnapsToDevicePixels=false
2号:SnapsToDevicePixels=true
3号:UseLayoutRounding=false
4号:UseLayoutRounding=true
5号:UseLayoutRounding=false,SnapsToDevicePixels=false
当你拖动window的边框改变window的大小时,这几个图标是上下移动,你会发现除了4号的样式是固定不变的(注意观察内部的白色叉号),其他几个的样式都在动态变化。
注意观察2号的头部,在某个像素位置与其他的相比是少了一部分的(不是等高的)。这就会产生一种不正常的效果,如果你的icon是一个圆形,当把它的宽高设置的比较小时会变成一个正方形或者长方形。

2.从字面意思看UseLayoutRounding有四舍五入取整的意思,而SnapsToDevicePixels没有
用UseLayoutRounding=true修饰一个Grid元素,设置grid的width为100,将grid等分为3列(设置每一列的width为*)。程序运行后可知这三列的ActualWidth里会有两个33和一个34。而如果设置UseLayoutRounding=false或者SnapsToDevicePixels=true,每一列的宽度都会为33.3333333333333,是均分的。

附有一个demo,有二者详细的比较(使用方法:新建解决方案,然后本项目添加进去,运行之后点击ImageWindow按钮。)。

另外,如果你在编码过程中发现设置UseLayoutRounding不管用,那就再设置下SnapsToDevicePixels吧!


参考:
When should I use SnapsToDevicePixels in WPF 4.0?
FrameworkElement.UseLayoutRounding Property
UIElement.SnapsToDevicePixels Property
Pixel Snapping in WPF Applications

目录
相关文章
WPF-Binding问题-模板样式使用Binding TemplatedParent与TemplateBinding区别
WPF-Binding问题-模板样式使用Binding TemplatedParent与TemplateBinding区别
229 0
|
C#
WPFのclipToBounds与maskToBounds的区别
原文:WPFのclipToBounds与maskToBounds的区别 UIView.clipsToBounds : 让子 View 只显示父 View 的 Frame 部分,子视图超出frame的部分不显示,默认为NO,设置为YES就会把超出的部分裁掉; maskToBounds : 是 CALayer 的属性,基于 View  的不少属性其实就是作用于 CALayer 的,子图层是否剪切图层边界,默认为NO UIView.layer.maskToBounds = YES 与 UIView.clipToBounds = YES 的效果是一样的。
1159 0
|
C#
WPF中Auto与*的区别
原文:WPF中Auto与*的区别 Auto 表示自动适应显示内容的宽度, 如自动适应文本的宽度,文本有多长,控件就显示多长.
867 0
|
C#
WPF中ControlTemplate和DataTemplate的区别
原文:WPF中ControlTemplate和DataTemplate的区别 下面代码很好的解释了它们之间的区别: ...
1582 0
|
C#
WPF ChangePropertyAction中TargetName和TargetObject的区别
原文:WPF ChangePropertyAction中TargetName和TargetObject的区别 在wpf页面布局中经常用到ChangePropertyAction来更改属性,在这个里面有TargetName和TargetObject两个属性,都表示需要修改的控件名称,那么这两个有什么区...
913 0
|
C# 前端开发 .NET
WPF中的资源简介、DynamicResource与StaticResource的区别
原文:WPF中的资源简介、DynamicResource与StaticResource的区别 什么叫WPF的资源(Resource)?资源是保存在可执行文件中的一种不可执行数据。在WPF的资源中,几乎可以包含图像、字符串等所有的任意CLR对象,只要对象有一个默认的构造函数和独立的属性。
1307 0
|
C# 调度
WPF中Timer与DispatcherTimer类的区别
前几天在WPF中写了一个轨迹回放的功能,我想稍微做过类似项目的,都晓得采用一个时间控件或者时间对象作为调度器,我在这么做的时候,出现了问题,于是将程序中的Timer换成了DispatchTimer,然后就可以了,特意在网上找了下这两者的区别,看到一篇比较详细的,并且有代码的博文,我就直接引用了,原文地址:http://www.cnblogs.com/zhchbin/archive/2012/03/06/2381693.html,我只附加上原文的代码。
762 0