简体   繁体   English

缩放比例为150%时,Windows窗体无法缩放高度

[英]Windows form not scaling height when display is scaled 150%

I've got this down to a very simple repro, and cannot figure out what is going wrong with this form. 我将其归结为一个非常简单的复制程序,无法确定此表单出了什么问题。 When run at 96 DPI / 100% scale it appears fine: 当以96 DPI / 100%比例运行时,它看起来很好:

在此处输入图片说明

But when run at 144 DPI / 150% scale (or even 96 DPI / 150% scale), everything scales except the form height: 但是,当以144 DPI / 150%比例(甚至96 DPI / 150%比例)运行时,除表格高度外,其他所有比例都会缩放:

在此处输入图片说明

Originally I thought this was a DPI issue, but after verifying that it repros at 96 DPI, I'm not sure what's going on. 最初我以为这是DPI问题,但是在确认它可以以96 DPI再现后,我不确定发生了什么。

There is nothing special going on with the dialog or control, other than specifically setting the font of the dialog, and setting the AutoScaleMode to DPI. 除了专门设置对话框的字体并将AutoScaleMode设置为DPI之外,对话框或控件没有什么特别的事情。 The form lives inside an assembly that is loaded automatically by the app. 表单位于由应用程序自动加载的程序集中。

I'm using .NET 4.7.2 and Windows 10. 我正在使用.NET 4.7.2和Windows 10。

Here's the form code: 这是表单代码:

using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FormTestLib
{
    partial class ValidatingSplash : Form
    {
        public ValidatingSplash()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.CenterToParent();
        }
    }
}

Here's the designer file: 这是设计器文件:

namespace FormTestLib
{
    public partial class ValidatingSplash
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ValidatingSplash));
            this.lblValidating = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // lblValidating
            // 
            this.lblValidating.Anchor = System.Windows.Forms.AnchorStyles.None;
            this.lblValidating.AutoSize = true;
            this.lblValidating.Location = new System.Drawing.Point(58, 45);
            this.lblValidating.Name = "lblValidating";
            this.lblValidating.Size = new System.Drawing.Size(166, 13);
            this.lblValidating.TabIndex = 7;
            this.lblValidating.Text = "Validating cached credentials...";
            // 
            // ValidatingSplash
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
            this.ClientSize = new System.Drawing.Size(274, 104);
            this.ControlBox = false;
            this.Controls.Add(this.lblValidating);
            this.Font = new System.Drawing.Font("Segoe UI", 8.25F);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "ValidatingSplash";
            this.Text = "Validating Credentials";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion
        private System.Windows.Forms.Label lblValidating;
    }
}

In the app.config I'm setting DpiAwareness according to the docs: 在app.config中,我根据文档设置DpiAwareness:

<System.Windows.Forms.ApplicationConfigurationSection>
  <add key="DpiAwareness" value="PerMonitorV2"/>
</System.Windows.Forms.ApplicationConfigurationSection>

And in the manifest I'm setting the compatibility: 在清单中,我设置了兼容性:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
  <application>
    <!-- Windows 10 compatibility -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
  </application>
</compatibility>

All this according to the instructions for high DPI support here . 所有这些都根据此处对DPI的高支持的说明进行。

The application code simply shows the dialog: 应用程序代码仅显示对话框:

namespace TestApp
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            // set the visual styles
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);

            ValidatingSplash Splash = new ValidatingSplash();
            Splash.ShowDialog();
        }
    }
}

Can anyone see what I might be doing wrong, or what I'm missing? 谁能看到我可能做错了什么,或者我错过了什么?

Thanks in advance! 提前致谢!

To follow Microsoft guidelines and provide High DPI support for your application you should change several things. 要遵循Microsoft准则并为您的应用程序提供High DPI支持,您应该更改几件事。 First of all in your Designer file of form change AutoScaleDimensions to AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 首先,在格式的Designer文件中,将AutoScaleDimensions更改为AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); . And AutoScaleMode to this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 然后将AutoScaleMode设置this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; .

In the application just use Application.SetCompatibleTextRenderingDefault(false); 在应用程序中,只需使用Application.SetCompatibleTextRenderingDefault(false);

I also added a small correction for for setting ClientSize of the form. 我还为设置表单的ClientSize添加了一个小的更正。 AdjustClientWidthToDPIScale() . AdjustClientWidthToDPIScale() Depending on DPI scale the client width of form is changed according to the DPI factor. 根据DPI比例,表格的客户宽度会根据DPI因子而变化。

All code is listed below. 下面列出了所有代码。

App.config file: App.config文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/>
    </startup>
      <System.Windows.Forms.ApplicationConfigurationSection>
    <add key="DpiAwareness" value="PerMonitorV2" />
  </System.Windows.Forms.ApplicationConfigurationSection>
</configuration>

Form code: 表单代码:

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FormTestLib
{
    public partial class ValidatingSplash : Form
    {
        public ValidatingSplash()
        {
            InitializeComponent();

            AdjustClientWidthToDPIScale();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.CenterToParent();
        }

        private void AdjustClientWidthToDPIScale()
        {
            double dpiKoef = Graphics.FromHdc(GetDC(IntPtr.Zero)).DpiX / 96f;

            int compansatedWidth = (int)(ClientSize.Width * dpiKoef);


            this.ClientSize = new Size(compansatedWidth, this.ClientSize.Height);
        }

        [DllImport("User32.dll")]
        private static extern IntPtr GetDC(IntPtr hWnd);
    }
}

Form designer : 表格设计师

    namespace FormTestLib
{
    partial class ValidatingSplash
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ValidatingSplash));
            this.lblValidating = new System.Windows.Forms.Label();
            this.SuspendLayout();

            // 
            // lblValidating
            // 
            this.lblValidating.Anchor = System.Windows.Forms.AnchorStyles.None;
            this.lblValidating.AutoSize = true;
            this.lblValidating.Location = new System.Drawing.Point(58, 45);
            this.lblValidating.Name = "lblValidating";
            this.lblValidating.Size = new System.Drawing.Size(166, 13);
            this.lblValidating.TabIndex = 7;
            this.lblValidating.Text = "Validating cached credentials...";
            // 
            // ValidatingSplash
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(274, 104);
            this.ControlBox = false;
            this.Controls.Add(this.lblValidating);
            this.Font = new System.Drawing.Font("Segoe UI", 8.25F);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            //this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "ValidatingSplash";
            this.Text = "Validating Credentials";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion
        private System.Windows.Forms.Label lblValidating;
    }
}

Apllication code : 应用代码

[STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        ValidatingSplash Splash = new ValidatingSplash();
        Splash.ShowDialog();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将开发从 100% 的 Windows 缩放转移到 150% 的 WinForms 窗口 - Moving development from 100% Windows scaling to 150% chops WinForms window 当DPI为150%时,我的表格无法正确打印 - My form is not printing correctly when DPI is 150% Windows Forms C# 应用程序 - 当用户为操作系统字体大小选择 125% 或 150% 时,设置表单控件的字体大小以适应屏幕? - Windows Forms C# application - Set font size of form controls to fit the screen when a user choose 125% or 150% for the OS font size? Windows窗体中的显示面板时出现错误 - error when display panel in windows form Windows窗体高度不一致 - Windows Form Height Inconsistency 如何获得 Windows 推荐的显示缩放比例? - How to get Windows recommended display scaling? 当原始图像的高度和宽度较小时,图像缩放不起作用 - Image scaling does not work when original image height & width is smaller the scaling height & width 以Windows形式限制菜单高度 - Limit menu height in Windows form 以Windows形式显示项目 - display items in a windows form 应用程序在比例为150%的监视器上正确显示,但不能在比例为100%的监视器上正确显示 - Application displays correctly on a 150% scaled monitor but not on a 100% one
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM