I've been working on a Windows Forms application, and have recently added a simple settings page that allows the user to select a folder for where the output goes. The OpenFileDialog is ugly and not nice to use, so I've added in the WindowsAPICodePack to get access to the CommonOpenFileDialog - all good there.
When I open the CommonOpenFileDialog, the Windows form application shrinks to a smaller size, as shown in the image attached.
On the left is the program normally, on the right is with the dialog open:
I've tried checking the size of the Form before and after, that's not changing, so I'm hitting a bit of a brick wall. Any information would be useful, I can provide more details if needed.
Code to open the dialog is:
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.DefaultDirectory = selectedFolderTextBox.Text;
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() != CommonFileDialogResult.Ok) return;
selectedFolderTextBox.Text = dialog.FileName;
This problem happens to me when I change the Scale and layout in windows Settings->System form 100% to a higher value. It probably has to do with high DPI and DPI scaling.
I found several solution:
Solution 1: Configuring Windows Forms for high DPI support
This solution is only for .NET Framework version 4.7 or higher.
Add this to to App.config file.
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Source: Configuring your Windows Forms app for high DPI support:
Enable per-monitor DPI awareness in the app.config file.
Windows Forms
introduces a new
System.Windows.Forms.ApplicationConfigurationSection element to
support new features and customizations added starting with the .NET
Framework 4.7. To take advantage of the new features that support high
DPI, add the following to your application configuration file.
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Important
In previous versions of the .NET Framework, you used the manifest to
add high DPI support. This approach is no longer recommended, since it
overrides settings defined on the app.config file.
Solution 2: Use Ookii.Dialogs.WinForms NuGet package
Use the Ookii.Dialogs.WinForms NuGet package. It doesn't have the shrinking problem. It has a VistaOpenFileDialog similar to the CommonFileDialog of WindowsAPICodePack. It also has a nice folder browser VistaFolderBrowserDialog like the CommonFileDialog with IsFolderPicker set to true.
Solution 3: Override high DPI scaling behavior for the .exe file
This solution requires to manually change the compatibility settings for each application .exe file individually, so it not the best solution.
To do this you need to right-click on the .exe file, select Properties->Compatibility->Change high DPI settings and check Override high DPI scaling behavior and select one of the options (see: How to use DPI scaling in Windows 10 to fix blurry old apps)
Enable dpi-aware by adding app.manifest file, and uncomment this blocks.
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
This works for me on my Surface Pro 4(dpi scale 200%).
Related
I've created a simple Winforms application in C#. When I run the application on a machine with high DPI settings (e.g. 150%), the application gets scaled up. So far so good!
But instead of rendering the fonts with a higher font size, all texts are just scaled up, too. That of course leads to very blurry text (on all controls like buttons etc.).
Shouldn't windows take care of rendering the texts correctly? For example my application's title bar is rendered crisp & clear.
Once you go past 100% (or 125% with the "XP-style DPI scaling" checkbox ticked), Windows by default takes over the scaling of your UI. It does so by having your app render its output to a bitmap and drawing that bitmap to the screen. The rescaling of that bitmap makes the text inevitably look fuzzy. A feature called "DPI virtualization", it keeps old programs usable on high resolution monitors.
You have to explicitly let it know that you can handle higher DPI settings by adding the <dpiAware> element to your manifest. The MSDN page is here but it isn't complete since it is omitting the UAC settings. Project + Add New Item, pick "Application Manifest File". Edit the manifest text or copy/paste this:
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
You can also pinvoke SetProcessDPIAware() in your Main() method, necessary for example if you deploy with ClickOnce:
[STAThread]
static void Main() {
if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // Edit as needed
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
UPDATE, this common need is finally a bit easier if you use VS2015 Update 1 or higher. The added manifest already has the relevant directive, just remove the comments.
Keyword for search so I can find this post back: dpiAware
Applications can be developed in two different mode.
The first one is to declare our application to be non-DPI-aware (not declaring anything will default to this). In this case the operating system will render our application under the expected 96 DPI and then will do to the bitmap scaling that we discussed before. The result will be a blurry looking application, but with a correct layout.
The second option is to declare the application as DPI-aware. In this case the OS will not do any scaling and will let your application render according to the original DPI of the screen. In case of a per-monitor-DPI environment, your application will be rendered with the highest DPI of all the screens, then this bitmap will be scaled down to the proper size for each monitor. Downscaling results in a better viewing experience than upscaling but you might still notice some fuzziness.
If you want to avoid that, you must declare your application as per-monitor-DPI-aware. Then you must detect when your application is dragged across different monitors and render according to the DPI of the current one.
Declaring the DPI awareness is done in a manifest file.
refer the following link stackoverflow
Using .NET Framework 4.7 and Windows 10 Creators Update (1703) or newer you must do the following things to configure high DPI support for your Windows Form application:
Declare compatibility with Windows 10.
To do this, add the following to your manifest file:
<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
Enable per-monitor DPI awareness in the app.config file.
Windows Forms introduces a new System.Windows.Forms.ApplicationConfigurationSection element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Important
In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file.
Call the static EnableVisualStyles method.
This should be the first method call in your application entry point. For example:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
The advantage of this is the support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.
Source: High DPI support in Windows Forms
None of these suggestions worked for me but, something happened after I removed the Form.Font = new ... from the Form.Design.cs, the form started to re-scale properly, it works if the Font is defined in the constructor or not at all. Why? somebody else may be able to explained, I just can talk about the changed I made and took me a few minutes to figured out it was the root cause for the form I was working on. Hope it helps.
Since at least Visual Studio 2017 you just have to add a manifest file and uncomment this section:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
This is not an answer. This is my work around. None of the above answers or comments worked for me. I also searched for and tried other methods.
I have been using Visual Studio.NET with C# and Windows.Forms since it was originally released. Until VS 2022 and Windows 11 this year, setting the scale mode seemed to work fine. For some reason, some of my Form.Height values get reduced at run time. No problems so far with Form.Width being changed. For me, this problem started April 1, 2022 - so I first thought it was an April Fool's prank!
Anyway, I have given up trying solutions for now and decided it is more practical for me to just set the Form.Size in the constructor code.
I observe the Designer UI uses Size which it converts to ClientSize in its generated code as follows:
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(744, 109);
this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
My workaround in my Form's constructor looks like:
/// <summary>
/// Constructor
/// </summary>
public MyForm()
{
// In the designer, MyForm.Size was entered and displayed as 760, 148
InitializeComponent();
// At runtime, MyForm.Size is changed to 760, 111
// I will Reset this form's Size here so I can get full height again.
this.Size = new Size(760, 148);
}
Platform:
Windows 11 Professional
Microsoft Visual Studio Professional 2022
Version 17.1.6
VisualStudio.17.Release/17.1.6+32421.90
Microsoft .NET Framework version 4.8.04161
C# Tools 4.1.0-5.22165.10+e555772db77ca828b02b4bd547c318387f11d01f
HDMI 1920x1080 video (100% or no scaling)
I've created a simple Winforms application in C#. When I run the application on a machine with high DPI settings (e.g. 150%), the application gets scaled up. So far so good!
But instead of rendering the fonts with a higher font size, all texts are just scaled up, too. That of course leads to very blurry text (on all controls like buttons etc.).
Shouldn't windows take care of rendering the texts correctly? For example my application's title bar is rendered crisp & clear.
Once you go past 100% (or 125% with the "XP-style DPI scaling" checkbox ticked), Windows by default takes over the scaling of your UI. It does so by having your app render its output to a bitmap and drawing that bitmap to the screen. The rescaling of that bitmap makes the text inevitably look fuzzy. A feature called "DPI virtualization", it keeps old programs usable on high resolution monitors.
You have to explicitly let it know that you can handle higher DPI settings by adding the <dpiAware> element to your manifest. The MSDN page is here but it isn't complete since it is omitting the UAC settings. Project + Add New Item, pick "Application Manifest File". Edit the manifest text or copy/paste this:
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
You can also pinvoke SetProcessDPIAware() in your Main() method, necessary for example if you deploy with ClickOnce:
[STAThread]
static void Main() {
if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // Edit as needed
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
UPDATE, this common need is finally a bit easier if you use VS2015 Update 1 or higher. The added manifest already has the relevant directive, just remove the comments.
Keyword for search so I can find this post back: dpiAware
Applications can be developed in two different mode.
The first one is to declare our application to be non-DPI-aware (not declaring anything will default to this). In this case the operating system will render our application under the expected 96 DPI and then will do to the bitmap scaling that we discussed before. The result will be a blurry looking application, but with a correct layout.
The second option is to declare the application as DPI-aware. In this case the OS will not do any scaling and will let your application render according to the original DPI of the screen. In case of a per-monitor-DPI environment, your application will be rendered with the highest DPI of all the screens, then this bitmap will be scaled down to the proper size for each monitor. Downscaling results in a better viewing experience than upscaling but you might still notice some fuzziness.
If you want to avoid that, you must declare your application as per-monitor-DPI-aware. Then you must detect when your application is dragged across different monitors and render according to the DPI of the current one.
Declaring the DPI awareness is done in a manifest file.
refer the following link stackoverflow
Using .NET Framework 4.7 and Windows 10 Creators Update (1703) or newer you must do the following things to configure high DPI support for your Windows Form application:
Declare compatibility with Windows 10.
To do this, add the following to your manifest file:
<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
Enable per-monitor DPI awareness in the app.config file.
Windows Forms introduces a new System.Windows.Forms.ApplicationConfigurationSection element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Important
In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file.
Call the static EnableVisualStyles method.
This should be the first method call in your application entry point. For example:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
The advantage of this is the support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.
Source: High DPI support in Windows Forms
None of these suggestions worked for me but, something happened after I removed the Form.Font = new ... from the Form.Design.cs, the form started to re-scale properly, it works if the Font is defined in the constructor or not at all. Why? somebody else may be able to explained, I just can talk about the changed I made and took me a few minutes to figured out it was the root cause for the form I was working on. Hope it helps.
Since at least Visual Studio 2017 you just have to add a manifest file and uncomment this section:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
This is not an answer. This is my work around. None of the above answers or comments worked for me. I also searched for and tried other methods.
I have been using Visual Studio.NET with C# and Windows.Forms since it was originally released. Until VS 2022 and Windows 11 this year, setting the scale mode seemed to work fine. For some reason, some of my Form.Height values get reduced at run time. No problems so far with Form.Width being changed. For me, this problem started April 1, 2022 - so I first thought it was an April Fool's prank!
Anyway, I have given up trying solutions for now and decided it is more practical for me to just set the Form.Size in the constructor code.
I observe the Designer UI uses Size which it converts to ClientSize in its generated code as follows:
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(744, 109);
this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
My workaround in my Form's constructor looks like:
/// <summary>
/// Constructor
/// </summary>
public MyForm()
{
// In the designer, MyForm.Size was entered and displayed as 760, 148
InitializeComponent();
// At runtime, MyForm.Size is changed to 760, 111
// I will Reset this form's Size here so I can get full height again.
this.Size = new Size(760, 148);
}
Platform:
Windows 11 Professional
Microsoft Visual Studio Professional 2022
Version 17.1.6
VisualStudio.17.Release/17.1.6+32421.90
Microsoft .NET Framework version 4.8.04161
C# Tools 4.1.0-5.22165.10+e555772db77ca828b02b4bd547c318387f11d01f
HDMI 1920x1080 video (100% or no scaling)
I've created a simple Winforms application in C#. When I run the application on a machine with high DPI settings (e.g. 150%), the application gets scaled up. So far so good!
But instead of rendering the fonts with a higher font size, all texts are just scaled up, too. That of course leads to very blurry text (on all controls like buttons etc.).
Shouldn't windows take care of rendering the texts correctly? For example my application's title bar is rendered crisp & clear.
Once you go past 100% (or 125% with the "XP-style DPI scaling" checkbox ticked), Windows by default takes over the scaling of your UI. It does so by having your app render its output to a bitmap and drawing that bitmap to the screen. The rescaling of that bitmap makes the text inevitably look fuzzy. A feature called "DPI virtualization", it keeps old programs usable on high resolution monitors.
You have to explicitly let it know that you can handle higher DPI settings by adding the <dpiAware> element to your manifest. The MSDN page is here but it isn't complete since it is omitting the UAC settings. Project + Add New Item, pick "Application Manifest File". Edit the manifest text or copy/paste this:
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
You can also pinvoke SetProcessDPIAware() in your Main() method, necessary for example if you deploy with ClickOnce:
[STAThread]
static void Main() {
if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // Edit as needed
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
UPDATE, this common need is finally a bit easier if you use VS2015 Update 1 or higher. The added manifest already has the relevant directive, just remove the comments.
Keyword for search so I can find this post back: dpiAware
Applications can be developed in two different mode.
The first one is to declare our application to be non-DPI-aware (not declaring anything will default to this). In this case the operating system will render our application under the expected 96 DPI and then will do to the bitmap scaling that we discussed before. The result will be a blurry looking application, but with a correct layout.
The second option is to declare the application as DPI-aware. In this case the OS will not do any scaling and will let your application render according to the original DPI of the screen. In case of a per-monitor-DPI environment, your application will be rendered with the highest DPI of all the screens, then this bitmap will be scaled down to the proper size for each monitor. Downscaling results in a better viewing experience than upscaling but you might still notice some fuzziness.
If you want to avoid that, you must declare your application as per-monitor-DPI-aware. Then you must detect when your application is dragged across different monitors and render according to the DPI of the current one.
Declaring the DPI awareness is done in a manifest file.
refer the following link stackoverflow
Using .NET Framework 4.7 and Windows 10 Creators Update (1703) or newer you must do the following things to configure high DPI support for your Windows Form application:
Declare compatibility with Windows 10.
To do this, add the following to your manifest file:
<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
Enable per-monitor DPI awareness in the app.config file.
Windows Forms introduces a new System.Windows.Forms.ApplicationConfigurationSection element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Important
In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file.
Call the static EnableVisualStyles method.
This should be the first method call in your application entry point. For example:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
The advantage of this is the support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.
Source: High DPI support in Windows Forms
None of these suggestions worked for me but, something happened after I removed the Form.Font = new ... from the Form.Design.cs, the form started to re-scale properly, it works if the Font is defined in the constructor or not at all. Why? somebody else may be able to explained, I just can talk about the changed I made and took me a few minutes to figured out it was the root cause for the form I was working on. Hope it helps.
Since at least Visual Studio 2017 you just have to add a manifest file and uncomment this section:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
This is not an answer. This is my work around. None of the above answers or comments worked for me. I also searched for and tried other methods.
I have been using Visual Studio.NET with C# and Windows.Forms since it was originally released. Until VS 2022 and Windows 11 this year, setting the scale mode seemed to work fine. For some reason, some of my Form.Height values get reduced at run time. No problems so far with Form.Width being changed. For me, this problem started April 1, 2022 - so I first thought it was an April Fool's prank!
Anyway, I have given up trying solutions for now and decided it is more practical for me to just set the Form.Size in the constructor code.
I observe the Designer UI uses Size which it converts to ClientSize in its generated code as follows:
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(744, 109);
this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
My workaround in my Form's constructor looks like:
/// <summary>
/// Constructor
/// </summary>
public MyForm()
{
// In the designer, MyForm.Size was entered and displayed as 760, 148
InitializeComponent();
// At runtime, MyForm.Size is changed to 760, 111
// I will Reset this form's Size here so I can get full height again.
this.Size = new Size(760, 148);
}
Platform:
Windows 11 Professional
Microsoft Visual Studio Professional 2022
Version 17.1.6
VisualStudio.17.Release/17.1.6+32421.90
Microsoft .NET Framework version 4.8.04161
C# Tools 4.1.0-5.22165.10+e555772db77ca828b02b4bd547c318387f11d01f
HDMI 1920x1080 video (100% or no scaling)
I am trying to make a per-monitor DPI aware application using C# .NET with regular windows forms (not WPF).
I understand the concept of opting into per-monitor DPI support, and have done this in the manifest:
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
</windowsSettings>
</application>
When I opt into that, my application does not change its pixel size at all when it is dragged from a 96DPI monitor (my default monitor) onto a 144DPI monitor (i.e. the application is pixel-for-pixel identical on both monitors, save for very slight differences in the minimize-maximize-close glyphs). Hence the application is very small and the text is hard to read on the 144DPI monitor.
It seems that the EnableWindowsFormsHighDpiAutoResizing setting has no effect, as my app displays in exactly the same way whether this setting is true or false, unless I have done something wrong in my app.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
</configuration>
Can anybody shed light on what this option does?
Is it part of the solution for writing a C# windows form application which will automatically resize itself when dragged from a 96DPI monitor onto a 144DPI monitor? (by automatic I mean, without me writing code to iterate over all the controls and set a custom scale factor).
I have done many hours of research into this problem and don't have a clear answer myself yet.
It seems that if I opt into per-monitor DPI awareness then I must hanldle the WM_DPICHANGED myself in order to do something. If that is the answer, so be it, but I really feel like I have missed some built in way of doing things.
"dpiAware = true" means application should handle the DPI change, otherwise Windows OS will scale the form/font for you. This is my understanding.
I've created a simple Winforms application in C#. When I run the application on a machine with high DPI settings (e.g. 150%), the application gets scaled up. So far so good!
But instead of rendering the fonts with a higher font size, all texts are just scaled up, too. That of course leads to very blurry text (on all controls like buttons etc.).
Shouldn't windows take care of rendering the texts correctly? For example my application's title bar is rendered crisp & clear.
Once you go past 100% (or 125% with the "XP-style DPI scaling" checkbox ticked), Windows by default takes over the scaling of your UI. It does so by having your app render its output to a bitmap and drawing that bitmap to the screen. The rescaling of that bitmap makes the text inevitably look fuzzy. A feature called "DPI virtualization", it keeps old programs usable on high resolution monitors.
You have to explicitly let it know that you can handle higher DPI settings by adding the <dpiAware> element to your manifest. The MSDN page is here but it isn't complete since it is omitting the UAC settings. Project + Add New Item, pick "Application Manifest File". Edit the manifest text or copy/paste this:
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
You can also pinvoke SetProcessDPIAware() in your Main() method, necessary for example if you deploy with ClickOnce:
[STAThread]
static void Main() {
if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // Edit as needed
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
UPDATE, this common need is finally a bit easier if you use VS2015 Update 1 or higher. The added manifest already has the relevant directive, just remove the comments.
Keyword for search so I can find this post back: dpiAware
Applications can be developed in two different mode.
The first one is to declare our application to be non-DPI-aware (not declaring anything will default to this). In this case the operating system will render our application under the expected 96 DPI and then will do to the bitmap scaling that we discussed before. The result will be a blurry looking application, but with a correct layout.
The second option is to declare the application as DPI-aware. In this case the OS will not do any scaling and will let your application render according to the original DPI of the screen. In case of a per-monitor-DPI environment, your application will be rendered with the highest DPI of all the screens, then this bitmap will be scaled down to the proper size for each monitor. Downscaling results in a better viewing experience than upscaling but you might still notice some fuzziness.
If you want to avoid that, you must declare your application as per-monitor-DPI-aware. Then you must detect when your application is dragged across different monitors and render according to the DPI of the current one.
Declaring the DPI awareness is done in a manifest file.
refer the following link stackoverflow
Using .NET Framework 4.7 and Windows 10 Creators Update (1703) or newer you must do the following things to configure high DPI support for your Windows Form application:
Declare compatibility with Windows 10.
To do this, add the following to your manifest file:
<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
Enable per-monitor DPI awareness in the app.config file.
Windows Forms introduces a new System.Windows.Forms.ApplicationConfigurationSection element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Important
In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file.
Call the static EnableVisualStyles method.
This should be the first method call in your application entry point. For example:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
The advantage of this is the support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.
Source: High DPI support in Windows Forms
None of these suggestions worked for me but, something happened after I removed the Form.Font = new ... from the Form.Design.cs, the form started to re-scale properly, it works if the Font is defined in the constructor or not at all. Why? somebody else may be able to explained, I just can talk about the changed I made and took me a few minutes to figured out it was the root cause for the form I was working on. Hope it helps.
Since at least Visual Studio 2017 you just have to add a manifest file and uncomment this section:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
This is not an answer. This is my work around. None of the above answers or comments worked for me. I also searched for and tried other methods.
I have been using Visual Studio.NET with C# and Windows.Forms since it was originally released. Until VS 2022 and Windows 11 this year, setting the scale mode seemed to work fine. For some reason, some of my Form.Height values get reduced at run time. No problems so far with Form.Width being changed. For me, this problem started April 1, 2022 - so I first thought it was an April Fool's prank!
Anyway, I have given up trying solutions for now and decided it is more practical for me to just set the Form.Size in the constructor code.
I observe the Designer UI uses Size which it converts to ClientSize in its generated code as follows:
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(744, 109);
this.ControlBox = false;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
My workaround in my Form's constructor looks like:
/// <summary>
/// Constructor
/// </summary>
public MyForm()
{
// In the designer, MyForm.Size was entered and displayed as 760, 148
InitializeComponent();
// At runtime, MyForm.Size is changed to 760, 111
// I will Reset this form's Size here so I can get full height again.
this.Size = new Size(760, 148);
}
Platform:
Windows 11 Professional
Microsoft Visual Studio Professional 2022
Version 17.1.6
VisualStudio.17.Release/17.1.6+32421.90
Microsoft .NET Framework version 4.8.04161
C# Tools 4.1.0-5.22165.10+e555772db77ca828b02b4bd547c318387f11d01f
HDMI 1920x1080 video (100% or no scaling)