Problems getting WinForms to scale correctly with DPI
Asked Answered
E

3

9

I'm running into problems with getting a WinForms app to display correctly at high DPI settings. I've checked various web sites, and the WinForms all have the correct AutoScaleMode. I've tried setting this to both DPI and Font. However, the forms always get cut off near the bottom when using high DPI settings (e.g. 125%).

I added some code to check, and if I set AutoScaleMode to DPI, when the form loads, I see that AutoScaleDimensions is 120,120 when the form loads, and CurrentAutoScaleDimensions is also 120,120. In the Form.designer.cs file, there is a line to set AutoScaleDimension to 96,96.

If I set AutoScaleMode to Font, then I can see in designer that AutoScaleDimension is correctly set to new System.Drawing.SizeF(6F, 13F), but when the form loads, both AutoScaleDimension and CurrentAutoScaleDimension are set to 8F,16F.

This app mixes some WPF with WinForms, and the WPF screens appear first. So based on DPI Scaling in .Net 3.5 in Mixed WinForms and WPF Application I tried setting the TextFormattingMode for the application, and for the WPF screens that show first, to "Display", but it makes no difference.

I am, frankly, at a loss as to what's causing this. I suppose I could add code to resize things programmatically by detecting the DPI at runtime, but I shouldn't have to do that. The AutoScaleMode (and related) properties are supposed to make this fairly automatic. So what else should I be checking for that might cause this problem?

Esteban answered 16/6, 2014 at 21:53 Comment(6)
125% is not "High DPI". WPF definitely has an impact, because it sets the High DPI aware flag at runtime, even if it isn't set in the manifest. WinForms might be confused about whether it is supposed to do the scaling or let the OS do so automatically.Hermann
Ben, sorry, I suppose "higher DPI" might be more accurate. I need to look at this in more detail, because the problem persisted even after I changed the app so we don't display the WPF screens first.Esteban
The modern %based settings make the whole higher/lower thing confusing. "Dots Per Inch" is lower for larger fonts. Old school DPI settings a lower number was used for higher fonts, newer versions of Windows assume a standard DPI and use a font size percentage so a higher value is used for higher fonts. It's generally less confusing to use actual numbers rather than higher/lower.Smuggle
Was this problem ever solved? I am experiencing something very similar which persists even after adding the <dpiAware> code to the application manifest as specified below.Advert
No, at least I was never able to fix it, and I had to move on to other things. In my case, I think it was because I had a mix of WinForms and WPF stuff mixed together. Eventually, if I can get that cleaned up, I'll take another look. Sorry I don't have a better answer.Esteban
this solution worked for me Add "[assembly: DisableDpiAwareness]" to AssemblyInfo.csSagitta
M
11

I had a similar problem just a few days ago. After a couple of hours research, I finally found a very simple solution -- adding <dpiAware> to the application manifest. Here is an example from Microsoft's website.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>True</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>

For my case, I need to set the <dpiAware> to Per-monitor to make it work normally. That is, change the line in the middle to <dpiAware>Per-monitor</dpiAware>.

The differences between each value are listed below(These are from MSDN):

  • False -- Sets the application to not DPI-aware.
  • True -- Sets the application to system DPI–aware.
  • Per-monitor -- On Windows 8.1, sets the application to per monitor-DPI aware. On Windows Vista through Windows 8, sets the application to not DPI–aware.
  • True/PM -- On Windows 8.1, sets the application to per monitor-DPI aware. On Windows Vista through Windows 8, sets the application to system-DPI aware.
Mallorca answered 3/10, 2014 at 16:3 Comment(0)
R
0

Is it possible that with the monitor size and the higher DPI setting, that the screen is simply no longer big enough to display your entire form? I say that because I'm developing a 1024 x 768 winforms app, and playing around with user DPI settings. If I set the DPI to 150% I can no longer see the bottom portion of the form on my monitor, yet the app is scaling correctly.

Rugby answered 1/7, 2014 at 16:47 Comment(1)
Good point, Jeff, but no, that's not what's happening here. The forms are still small enough to fit on screen, just not sized correctly.Esteban
I
0

Dotnet 6 and higher

It works on dotnet 8 Desktop

.Net5vs6

Please try to add this line to the Program.cs

class Program
{
    [STAThread]
    static void Main()
    {
...
        Application.SetHighDpiMode(HighDpiMode.DpiUnaware); // <-----
...
    }
}

For having the best result try every HighDpiMode mode. DpiUnaware worked for me, because I designed my form with more than 100%(175%). It depends on your situation.

Resource

https://learn.microsoft.com/en-us/dotnet/desktop/winforms/whats-new/net60?view=netdesktop-6.0#new-application-bootstrap

Itinerant answered 22/12, 2023 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.