Form Shrinking Issue After using a Custom ImageListView Control

后端 未结 1 1822
迷失自我
迷失自我 2021-01-16 10:39

I\'m using the following control for loading images in winforms.

https://www.codeproject.com/Articles/43265/ImageListView

(OR)

https://github.com/ooz

1条回答
  •  生来不讨喜
    2021-01-16 11:43

    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
        
       
    

    0 讨论(0)
提交回复
热议问题