5
votes

Our WPF application, using .NET 4.5, has UseLayoutRounding on by default at the root level of each window. On Windows 7 and Windows 8, our application looks good at 100% and 125% DPI settings. However, once we bump it up to 150%, we start having issues with double thick border lines throughout the product. If we turn UseLayoutRounding off at 150%, suddenly controls and borders look much better. We're investigating having this setting be dynamically set based on the DPI.

What I'm trying to understand is how a monitor's physical DPI plays into this. Could I expect that a 1080p monitor with a higher than normal DPI would not exhibit this kind of problem? If I ran my app on a Surface Pro (which we unfortunately don't have) with 200% DPI scaling turned on, would I see the same issues?

I guess what baffles me is that UseLayoutRounding does exactly what we want it to do when it comes to lining up adjacent borders and shapes at 100% and 125%, but then the opposite is true at 150%. Does anyone have any insights here?

1
I imagine this is because 150% x 1 = 1.5, which rounds up to 2. One experiment to validate this hypothesis would be to try a border thickness of 0.9 and see if this rounds to width 1 at 150%.Dan Bryant
Turns out you're right. Now I'm considering whether or not to change our default border thickness to 0.9, since it appears to look good even at 200%.Sean Beanland
The border thickness .9 trick fixed a weird double border (on part) of a tab control I had on a 4k monitor (.Net Core 3.1).b.pell

1 Answers

5
votes

WPF released a fix for clipping in Visuals on high DPI. In order to get this behavior on an app targeting TFV < 4.6, you need at to add the following in the runtime section of your app.config file :

<AppContextSwitchOverrides value="Switch.MS.Internal.DoNotApplyLayoutRoundingToMarginsAndBorderThickness=false;" />

Note: This will only work on a machine which has atleast .NET 4.6 installed. If your app targets framework version >= 4.6, then you don't even need to put this switch and should get the good behavior by default.