My Winforms application appears very blurry when executed without a manifest file. With it and the added code
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
the blurriness does disappear, but it requires the user to have an additional .config file to make the app look crisp when running it. I have tried setting the AutoScaleMode variable of my form to Font and Dpi, neither made a difference. I have also found online the SetProcessDpiAwarenessContext function, but I'm unsure if this is what I'm looking for and I do not know how to implement it into my code.
Is it possible to remove the blurriness from my app without a manifest file at all?
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 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%).
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 just started learning how to develop for Android a few days ago, so I'm still in the process of learning all the ins and out of the environment. Recently, I finished writing the functionality for a basic Contacts app and decided to turn to fixing some of the finer points of the UI. I have been trying for the last couple of days to change the launcher icon for the app from the default Android icon Default Icon to one that I selected Selected Icon. However, nothing I seem to try will allow the icon I selected to appear on the device I am testing on.
I added what is supposed to be the proper line in the Android Manifest file as seen here:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="Contact_Manager.Contact_Manager" android:versionCode="1" android:versionName="1.0" android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="16" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application android:label="Contacts" android:icon ="#drawable/contacts-3"></application></manifest>
But this solution did not work. I also tried deleting the default icon from the drawable folder(I also saved a copy of it elsewhere) but it still showed the default Icon on the device screen. I then tried to uninstall the application on the device in order to clear all the cache files, but was met with the same outcome. Is there something I'm doing wrong?
Note: I am also new to StackOverFlow so I apologize if the formatting of this question is awful.
I suspect you have not deleted all the versions of default icon. In android there is a icon for each screen density in drawable-mdpi, drawable-hdpi, etc folder. Hence search for that file and remove it from all the folders and try again.
You need to add fresh icons for each density.
UPDATE 1 :
I think I know the problem now. Right click the project on solution explorer. Then click on options. Then Build-Android Application.
Change the application icon there.
Delete the default icon.png files from all the Android drawable folders, and save your new icon as icon.png. Also make sure that in the manifest you point to the icon file:
<application android:label="<Your app name>" android:icon="#drawable/icon"></application>
Try with a different icon name
Copy the new icon(myIcon.png) into mipmap- folders.
Update the icon value in Android project MainActivity.cs file
Uninstall the application from your device and try again.
Had the same issue. Deleted the old icons (maybe you only removed them from project not deleted them? I dont know) and tried building. It threw errors wherever the old icon was referenced so I was able to trace the issue. Also removing the old and adding the new with the same name (Icon.png) worked for me
All of a sudden I start getting this error while trying to open 2 of some 10+ forms in my Window Forms application in designer.
To prevent possible data loss before loading the designer, the following errors must be resolved:
The key 'UserID' does not exist in the appSettings configuration section.
It used to work fine and I dont' remember doing significant changes to it.
The key, of course, is in the appSettings alright, and always was, and the application builds and executes as expected. Only design view for these 2 forms is unaccessible.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Server" value="MYSERVER" />
<add key="DataBase" value="MYDB" />
<add key="UserID" value="MYUSER" />
<add key="PassWord" value="MYPASS" />
</appSettings>
</configuration>
One of them is just a Form, the other is a UserControl. None of them inherits from abstract classes or anything like that. Rebuilding or restarting Visual Studio does not help so far.
Any ideas on fixing it?
And finally, here is what the designer REALLY was complaining about:
I had a call to a stored procedure right from the User Control's InitializeComponent().
While it may not be a good idea indeed (separate question material?), I have to say that the error was not presented to me in the best possible way...
Is it possible the config file was moved to a different folder or a new config file was introduced somewhere?
Okay, there is something else in common with these 2 forms - they both use one UserControl and there is another error in the designer which says
"The variable 'myControl' is either undeclared or was never assigned."
(where myControl is the User Control).
Maybe I should manually delete it and try re-adding through the designer.
You might check to make sure your XML is well-formed. I'm relying on memory here, but I recall getting this error once after copying settings between different config files and the only problem was that I'd overwritten an extra angle bracket when pasting.