Getting the Crisp back into your WPF Apps

WPF has a lot of advantages, it's perfectly sane data binding mechanism being one of the most outstanding ones.On the flipside, many people (meaning companies, mostly) have refused to switch from WinForms to WPF because of the "blurry" looks of applications written in WPF.

This blurryness goes back to two mechanisms:

1)Text Smoothing
Instead of relying on the system's ClearType mechanism, WPF does it's own thing-a-magic, which is blatantly inferior to the aforesaid. In fact, WPF smoothed fonts are a definite way to headaches, if read for some time.



Note : The image is from a website that compares various Microsoft.Net Font-Smoothing implementations.

They might be useful to integrate text in images, though.For business applications (displaying data grids etc.) this is a K.O. criterion. Nobody wants to have to take their glasses off in order to achieve readability, and nobody wants their software deployed along with a pack of aspirins.

2)SubPixel positioning



Based on the fact that the WPF Engine positions Elements not only on pixel positions but also somewhere between them, it has to calculate values for the neighboring pixels in order to display graphical objects (controls, images,...).
In that respect, WPF is a little over-achiever! The result is a pixel with a color value based on those of two or four surrounding pixels, visibly as crisp as a drop of ink in a water jar.

What we initially hoped to be a cure, turned out to be ineffective : The SnapsToDevicePixels Property. I have tried adding it to all hierarchies of the visual stack, but without any trace of success.

By default, WPF uses what it can to achieve a smooth look, so those mechanisms are set to work by default. For years, Microsoft has either ignored or not been able to satisfy the community's yell for help. Finally, with the release of WPF4, the options to switch those mechanisms off, are here!
Here's two steps to get your crispiness back :

1) TextFormattingMode
To get rid of WPF Not-So-ClearType font rendering, your root element should set the property TextOptions.TextFormattingMode to "Display". This, like Renderoptions.BitmapScalingMode, is an attached Property and can be set on a per-control level as well.


2) UseLayoutRounding
Using Layout rounding solves all issues based on SubPixel positioning, as it moves the elements to pixel positions instead.
That being said, it does what we would have expected SnapsToDevicePixels to do. As far as I have tested, all declarations of SnapsToDevicePixels can now safely be removed.
Fortunately, it has to be declared at top level, so
Further details on Layout Rounding can be read here .

If your Images are scaled rather than used in their "native size", you might want to set the BitmapScalingMode property of your Top-Level declaration (e.g. Window or Page) to utilize HighQuality rendering.

That should cease the era of the WPF-headache! All hail to King Crispy!

Kommentare

Beliebte Posts aus diesem Blog

Using AutoMapper for MVVM implementations

Deploying ClickOnce-applications in different environments without modifying the assembly identity

Preparing for and passing MCTS exam 70-536