我正在使用以下控件在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选件后

c# - 使用自定义ImageListView控件后的窗体缩小问题-LMLPHP

不使用DpiAware选项

c# - 使用自定义ImageListView控件后的窗体缩小问题-LMLPHP

最佳答案

我已经能够重现该问题,这有点奇怪。由于我怀疑该应用程序未声明为可识别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/

10-12 12:43
查看更多