70

Can anyone suggest a guideline on when to use SnapsToDevicePixels in WPF 4.0?

Should it only be used occasionally if there is an issue, liberally throughout an App, only on certain controls or what?

Mike B
  • 2,592
  • 3
  • 33
  • 46
  • 4
    I like to think that clean, crisp lines make your application feel professional and manicured. So, my advice is to use it wherever it aids that goal. – cplotts Apr 08 '10 at 17:16

4 Answers4

98

Good answers by Spencer and Martin as to the when to align your pixels.

As to the how: I would also point out that one should in WPF 4.0 try using the property UseLayoutRounding instead of SnapsToDevicePixels.

UseLayoutRounding makes what you are doing compatible with Silverlight (SnapsToDevicePixels is not available in Silverlight) ... and Microsoft is also encouraging the use of UseLayoutRounding over SnapsToDevicePixels in its documentation.

What is the difference between the two? Well, one big difference is that UseLayoutRounding occurs during the layout phase while SnapsToDevicePixels occurs during the render phase. This makes me speculate that UseLayoutRounding is probably a more performant way to go (I haven't confirmed this, though).

All that being said, there will still be reasons to use SnapsToDevicePixels. In fact, the MSDN documentation points to one. I will add another: it is only with SnapsToDevicePixels that you can use guidelines for precise control.

Here are some resources on this matter (i.e. pixel snapping and clarity with images, text, and visuals):

Heh. I know my answer was a little more than what you were asking for ... but this concept (i.e. resolution independence and the resulting problems it brings and how to get over them) can often be a point of frustration when working with WPF. At the very least, I wanted to point you to the new WPF 4.0 property, UseLayoutRounding.

UPDATE

I just have to add since I've seen this over and over ... sometimes SnapsToDevicePixels works when UseLayoutRounding doesn't. I wish I could put a finger on why this is the case, but definitely try UseLayoutRounding first and if that doesn't work, don't hesitate to try SnapsToDevicePixels.

That line is so sharp it can cut you!

FlyingFoX
  • 3,379
  • 3
  • 32
  • 49
cplotts
  • 13,941
  • 9
  • 55
  • 66
  • More = Better in many cases, this is a great answer to many questions I have been having, especially since I am begging to get the feeling that I had better port my WPF/Linq to SQL app over to Silverlight/Linq to EF – Mike B Apr 09 '10 at 01:20
  • 1
    @Peretz probably not noticeably ... but turning it on does add something that must be done/calculated. Maybe the effect would be noticeable if you had a ton of visuals. More likely, though, the perf hit would be lost in the generally bad performance. – cplotts Sep 29 '12 at 10:35
8

One case is if you are displaying an image or video. If you don't snap to device pixels (ie to the video screen's pixels) then some algorithm (interpolation, anti-aliasing) is used to position your image's pixels "in between" your screen's pixels, and what is displayed won't look as good as the original image would. The image would lose some sharpness.

Warpin
  • 6,971
  • 12
  • 51
  • 77
8

It should be used on controls or areas where the placement of the pixels has meaning. Controls relating to the canvas of a drawing application would be one example. Have you ever seen the map of a fragmented drive? This might be another example.

One exception I can think of is when you're using divider lines of some kind. Most people expect border lines to be solid. If this setting is off they can look blurred and distracting.

Basically if blurred edges = bad then turn it on

dss539
  • 6,804
  • 2
  • 34
  • 64
Spencer Ruport
  • 34,865
  • 12
  • 85
  • 147
  • 12
    You probably mean *"if edges are blurred - turn it on"* (set `SnapsToDevicePixels = true` to remove blurriness) . – Sinatr Sep 14 '15 at 14:24
4

Just noticed that it is very usefull for Borders. Additional info here.

<Style TargetType="Border" >
        <Setter Property="SnapsToDevicePixels" Value="True" />
</Style>