我正在使用以下控件在winforms中加载图像。
https://www.codeproject.com/Articles/43265/ImageListView
(要么)
https://github.com/oozcitak/imagelistview
在1080P 15英寸笔记本电脑上似乎存在与此控件相关的缩放问题,而在24英寸1080P显示器上无法重现
我最近注意到表单缩放发生了一件奇怪的事情。直接从GitHub下载的主解决方案以及在我自己的应用程序中都会发生这种情况。我的PC显示设置被设置为将显示比例缩放到125%(右键单击桌面->显示设置->更改文本,应用程序和...的大小)
当我开始调试时,表单加载-正确缩放。但是,一旦我在树形视图中单击包含图像的文件夹,图像就会被加载,并且表单将被缩放回100%。因此,整体形式似乎会立即缩小,而Windows的其余部分仍处于125%的水平。
我不确定这是Windows还是.Net Framework错误,还是执行控件的方式。也许有一个我不知道的属性需要更改?
任何帮助/建议将不胜感激!
更新:
使用DpiAware选件后
不使用DpiAware选项
最佳答案
我已经能够重现该问题,这有点奇怪。由于我怀疑该应用程序未声明为可识别DPI,因此将其设置为可识别DPI可解决表单更改大小的问题。这可以通过将清单文件添加到项目中来完成(项目菜单->添加新项->常规选项卡->选择“应用清单文件”。然后将以下内容添加到文件中:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
这就解决了问题,但是我很好奇为什么代码会采用这种方式。该过程以不了解DPI的过程开始,并且在关闭图像选择对话框后,将其转换为可以感知DPI的过程。可以使用SysInternal的Process Explorer应用程序进行观察。我的第一个想法是搜索对SetProcessDpiAwareness的调用,但是没有结果。深入研究代码发现,已调用
InitViaWpf
中的MetadataExtractor.cs
方法。此方法和其他方法利用System.Windows.Media.Imaging
命名空间中的类。看起来WPF库的这种用法使应用程序变为DPI感知,就像WPF应用程序默认为DPI感知一样。为名为USEWIC的ImageListView
项目声明了一个条件编译符号,该条件编译符号控制WPF类的这种用法。在项目的属性构建配置中删除该符号将阻止其使用,并且可以用作替代解决方案,它可能比声明Winform应用程序为DPI感知的方法更为可取,但是我没有时间进一步研究该库。编辑:通过在尚未标记为支持DPI的Winform应用程序中创建BitmapFrame实例,可以轻松复制此行为。
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);
}
}
}
}
编辑2:DPI感知winform缩放过程。
步骤1:在设计器中,将AutoScaleMode属性设置为Inherit。我知道没有任何意义,但是“继承”是真正的默认设置。
步骤2:修改窗体的构造函数以使用Dpi或Font自动缩放。这样做是为了防止设计人员记录不正确的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;
}
编辑3:要在使用WPF库的DPI感知应用程序上维护DPI虚拟化(防止自动切换到DPI感知),请在app.manifest文件中包含
dpiAware
部分,但明确将其设置为false。 <application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
关于c# - 使用自定义ImageListView控件后的窗体缩小问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42437903/