One of the main claimed benefits of WPF is “resolution independence”. Often this benefit is described in relatively vague terms leading people to believe that it means that the same WPF window will display on any monitor at the same size regardless of the resolution at which that monitor is set.
For example, one might imagine that if a user originally sets his monitor to a resolution of 1280 x 960 and later changes it to 640 x 480, a WPF window which was originally sized at 4″ x 4″ at the higher resolution should still display at that same size even after the monitor’s resolution has been changed. Unfortunately, a simple experiment will prove that this interpretation of “resolution independence” is not correct.
Another potential interpretation of this term is that a WPF window will display at the same size regardless of the monitor DPI setting. Right click Desktop, Properties, Settings, Advanced. On this property page you will see a combo box which is typically set to “Normal size(96 DPI)”.
Other options (at least under Windows XP) are “Large size (120 DPI)” and “Custom setting…”. One might reasonably hypothesize that since resolution independence evidently does not refer to the actual resolution at which the monitor is set (1200 x 960 vs. 640 x 480), that perhaps what is meant that a WPF window will display at the same size regardless of what DPI setting this property is set too. Again, unfortunately, another simple experiment will prove that this interpretation of “resolution independence” is equally invalid.
As it turns out, Microsoft was not really lying about the resolution independence of WPF. It is just that the explanation of what is meant by this term is a bit more complicated. The following experiments do indeed show that WPF is actually resolution independent.
We’ll do our verification by running a WPF test app on two systems with LCD displays that have different physical pixel sizes. The test app simply draws a 4 inch line whose length we will verify by putting a physical ruler beside it on the screen. The two test systems are as follows:
System 1: Desktop LCD monitor:
Screen width x height in pixels: 1600 x 1200
Screen width x height in inches: 17.0 x 12.75.
Therefore it has 1600 / 17.0 = 94 physical pixels per inch (physical DPI) horizontally and 1200 / 12.75 = 94 physical DPI vertically.
System 2: Laptop with LCD screen:
Screen width x height in pixels: 1400 x 1050
Screen width x height in inches: 12.0 x 9.0.
Therefore it has 1400 / 12.0 = 117 physical DPI horizontally and 1050 / 9.0 = 117 physical DPI vertically.
The key here is that the desktop monitor’s pixels are 25% larger than the laptop’s. (117 / 94 = 1.25)
Before doing the tests we need to review some terminology. While a classic Win32 app uses coordinates with units of “physical pixels”, a WPF app uses coordinates which are expressed in “device independent units” (DIUs we’ll call them here). One WPF DIU is defined as 1/96 of an inch. This definition of units allows WPF coordinates to be specified in inches rather than physical pixels. So a third possible interpretation of the term “resolution independence” might be that the same WPF application would display at the same size on two different monitors set to the same resoultion (1024 x 768 for example), regardless of the size of their physical pixels. Under this theory a dialog box that is 4 inches wide on System 1’s 94 physical DPI LCD should still be 4 inches wide on System 2’s denser 117 physical DPI LCD.
Unfortunately, the initial results of my experimentation seem to be at odds with this hypothesis. The following photos show that a line which is 384 DIUs wide actually displays at 4.08″ wide on my desktop monitor and at 3.28″ wide on my laptop monitor. Neither monitor achieves the desired result of displaying a 384 DIU long line at 384/96 = 4.00″.
The correct explanation, however, lies in a careful analysis of the interaction between two important display properties settings. The first is the screen resolution setting (eg. 1024 x 768) and the second is the “Advanced / DPI setting”. (See images above.) Both of them act as “scale factors” that let individual users force everything on their monitor to be displayed either bigger (for easier reading) or smaller (for more desktop real estate).
We can eliminate the first scale factor from our tests by requiring that the “screen resolution” be set to the “native resolution” of the system’s LCD display. Since System 1 has a physical resolution of 1600×1200 pixels we must assure that its screen resolution has been set to the same 1600 x 1200 pixels. In the case of System 2, the corresponding setting is 1400 x 1050.
The second scale factor, the “DPI setting”, is what we will vary in our tests. WPF doesn’t independently know what your monitor’s actual physical DPI value is. Instead WPF uses the current setting of this second scale factor the “DPI setting”. If the “DPI setting” does not match the true physical DPI, then WPF’s “resolution independence” will appear to break — although it really doesn’t.
Now let’s examine our full test results. We’ll begin with the 94 physical DPI desktop LCD.
For the first test we’ll use Windows default “DPI setting” of “Normal size (96 DPI)”, which is what most people use. The photo shows the line which we expect to be 4 inches actually measures 4.08 inches, which is 2% off. Why? Because our LCD only has a physical DPI of 94, but the “DPI setting” scale factor is telling WPF to act as if we have a 96 physical DPI display (also 2% off from the real 94 physical DPI).
Next let’s try tweaking the “DPI setting” to make everything larger and easier to read. For that we’ll change it to “Large size (120 DPI)”. Now the line we might have expected to be exactly 4 inches long actually measures 5.10 inches. Again the explanation is that we are “lying” to WPF about our monitor’s DPI. WPF acts as if it is running on a 120 DPI screen when in reality the physical DPI is actually only 94. The distortion ratios still match exactly: 120/94=1.28 and 5.10/4.00=1.28. Both are 28% off.
Finally we will try the rule suggested earlier. We’ll make a custom “DPI setting” of 94 DPI so that it matches the 94 physical DPI of this LCD. At last success! Now the photo of the ruler against the screen shows we are rendering a “4 inch” line that truly is exactly 4 inches long.
Having successfully explained all the test discrepancies for the 94 physical DPI desktop LCD, now let’s switch to the laptop LCD which has a physical DPI of 117 to see if the same experiment with this monitor will give us the same result.
For the first test we’ll again use Windows default “DPI setting” of “Normal size (96 DPI)”. This time the photo shows the line that we expect to be 4 inches actually measures only 3.28 inches, which is 18% smaller. Why? Because our LCD has a physical DPI of 117, but the “DPI setting” scale factor is telling WPF to act as if we have a 96 physical DPI display. Again the distortion ratios match exactly: 3.28/4.00=0.82 and 96/117=0.82. Both are 100-82=18% off.
For the final test we will again try the rule suggested earlier. We’ll make a custom “DPI setting” of 117 so that it matches the 117 physical DPI of the laptop’s LCD. Again the rule works! Now the photo shows our app is rendering a “4 inch” line that truly is 4 inches long.
In conclusion, we’ve seen that WPF really is resolution independent as long as Windows display properties scale factor settings are properly taken into account. What WPF Resolution Independence really means that two monitors set to their native resolution and which are accurately reporting their DPI settings to WPF will display the same WPF window at the exact same size. Under those conditions a monitor with 96 physical pixels per inch will display any WPF window at the same size as a monitor which has 192 physical pixels per inch. The only difference between the two is that the latter monitor will look much sharper than the former.