question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Setting/Getting HighDpiMode in WinForms Core Apps

See original GitHub issue

Rationale

Developers in WinForms Core currently have no way to set the HighDPI mode in their WinForms App. In a future version of .NET Core 3.0, this will again be possible via App.Manifest; however, a change in the settings requires then their app to be rebuilt. The previous option in the classic framework to control this setting via App.Config has been completely dropped in .NET Core. Currently, the only way to set the HighDPIMode is via P/Invoke. The Application.SetHighDpiMode method and Application.HighDpiMode property are an easy to apply and to discover alternative.

Proposed API

namespace System.Windows.Forms
{
    public sealed class Application
    {
        // Existing methods/properties (excerpt)
        public static void EnableVisualStyles();
        public static bool RenderWithVisualStyles { get; }

        // Proposed method/property
        public static bool SetHighDpiMode(HighDpiMode highDpiMode);
        public static HighDpiMode HighDpiMode { get; }
    }

    public enum HighDpiMode
    {
        DpiUnaware,
        SystemAware,
        PerMonitor,
        PerMonitorV2,
        DpiUnawareGdiScaled
    }
}

Description

Following EnableVisualStyles()/RenderWithVisualStyles of the Application class, we propose the method SetHighDpiMode which switches to the corresponding HighDPI mode, if that HighDPIMode setting a) has not been set before by other means (App.Manifest, P/Invoke before Application.Run – in this case the value to be set is ignored), and b) that HighDPIMode setting was set via SetHighDpiMode before calling Application.Run (or the first UI Element has been rendered).

Possible settings values are provided by the HighDpiMode Enum:

  • DpiUnaware
  • SystemAware
  • PerMonitor
  • PerMonitorV2
  • DpiUnawareGdiScaled

If a setting is attempted to be set which is not supported by the underlying OS, SetHighDpiMode automatically assumes the next possible setting on that OS; SetHighDpiMode never directly triggers an exception, but gives feedback as to whether the setting could be successfully set (true) or not (false).

In addition developers can query the actual setting of the current HighDpiMode at any time using the Application.HighDpiMode property, which returns one of the available HighDpiMode Enum values.

In the current implementation, we should limit the method/property to the process DpiAwareness rather than a Window DpiAwareness, and should probably think about extending this to a static method/property of the Control class to the windows DpiAwareness (@Tanya-Solyanik, thoughts?).

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:4
  • Comments:14 (12 by maintainers)

github_iconTop GitHub Comments

4reactions
Tanya-Solyanikcommented, Dec 5, 2018

FYI, steps to set DPI Awareness using the manifest file:

  • Add application manifest to your .NET Core project.

  • Uncomment the DPI-Awareness element, dpiAwareness element is supported as well., as manifest resource is processed by the windows code same as it is processed for a native app.

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>

  • Uncomment Windows10 as a supported OS
    <!-- Windows 10 -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
  • Add this manifest to your project file
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
  <PropertyGroup>
   <Win32Manifest>app1.manifest</Win32Manifest>
   </PropertyGroup>
</Project>
  • dotnet run
2reactions
lhakcommented, Dec 7, 2018

I agree that supporting high dpi is currently very challenging (to put it nicely) in winforms. I did a quick search in the winforms codebase and there is a lot of code in the individual controls to deal with this issue. I think the best (maybe only?) way to actually fix it completely would be to use effective pixels like on UWP/WPF. This way, most applications will not have to deal with handling different scaling factor at all (maybe only provide bitmap images in multiple sizes). The transformation between effective and physical pixels can then be handled by the low level rendering code.

Read more comments on GitHub >

github_iconTop Results From Across the Web

High DPI support - Windows Forms .NET Framework
Configuring your Windows Forms app for high DPI support. The new Windows Forms features that support high DPI awareness are available only in ......
Read more >
Application.SetHighDpiMode(HighDpiMode) Method
One of the enumeration values that specifies the high DPI mode to set. Returns. Boolean. true if the high DPI mode was set;...
Read more >
How to set EnableWindowsFormsHighDpiAutoResizing to ...
I have a WinForm application and I am migrating it from .net-framework to .net-core. In .Net Frameworks, I use the app.config file to...
Read more >
WinForms Scaling at Large DPI Settings–Is It Even Possible?
How can you scale WinForms apps today? ... The main idea is to set DPI scaling to top level windows that is different...
Read more >
Creating High DPI Ribbons for WinForms .NET 5
NET Core 3.0, Microsoft introduced a new way to set a high DPI mode for Windows Forms. A static method called Application.SetHighDpiMode( ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found