I\'m using the following control for loading images in winforms.
https://www.codeproject.com/Articles/43265/ImageListView
(OR)
https://github.com/ooz
I have been able to reproduce the issue and it is a bit strange. As I suspected the application is not declared to be DPI-aware and setting it to be DPI-aware resolves the issue of the form changing size. This can be done by adding a manifest file to the project (Project Menu->Add New Item->General Tab->Select "Application Manifest File". Then add the follow to the file:
true
That clears up the issue, but I was curious as to why the code was behaving this way. The process starts out as DPI-unaware and after closing the image selection dialog, it some how switched to being a DPI-aware process. The can be observed using the SysInternal's Process Explorer application. My first thought was to to search for a call to SetProcessDpiAwareness, but that yielded no results. Digging into the code revealed that the InitViaWpf
method in MetadataExtractor.cs
is called. This method and others utilize classes from the System.Windows.Media.Imaging
namespace. It appears that this usage of the WPF libraries causes the application to become DPI-aware in the same way that WPF applications are DPI-aware by default. There is a conditional compilation symbol declared for the ImageListView
project named USEWIC that controls this usage of the WPF classes. Removing this symbol in the project's properties build configuration will prevent their usage and can be used as an alternative solution and may be preferable to declaring the Winform application as being DPI-aware, but I don't have the time to investigate this library further.
Edit: This behavior can be easily replicated by creating an instance of BitmapFrame in a Winform application that has not been marked as being DPI-aware.
using System.Windows.Forms;
using System.IO;
using System.Windows.Media.Imaging;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (Stream strm = File.OpenRead("someimage.jpg"))
{
BitmapFrame frame = BitmapFrame.Create(strm, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None);
}
}
}
}
Edit 2: Procedure for DPI-aware winform scaling.
Step 1: In the designer, set the AutoScaleMode property to Inherit. I know None would make sense, but Inherit is the true default setting.
Step 2: Modify the Form's constructor to use either Dpi or Font automatic scaling. This is done to prevent the designer from recording improper AutoScaleDimensions.
public Form1()
{
InitializeComponent();
// Select either Dpi or font scaling
this.AutoScaleDimensions = new SizeF(96, 96);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
//this.AutoScaleDimensions = new System.Drawing.SizeF(6.0F, 13.0F);
//this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
Edit 3: To maintain the DPI-virtualization (prevent the automatic switching to DPI-aware) on a DPI-unaware application that uses WPF libraries, include the dpiAware
section in the app.manifest file, but explicity set it to false.
false