1

我已经把它归结为一个非常简单的复制品,并且无法弄清楚这个表格出了什么问题。当以 96 DPI / 100% 比例运行时,它看起来很好:

在此处输入图像描述

但是当以 144 DPI / 150% 比例(甚至 96 DPI / 150% 比例)运行时,除了表单高度之外,所有内容都会缩放:

在此处输入图像描述

最初我认为这是一个 DPI 问题,但在验证它以 96 DPI 重现后,我不确定发生了什么。

除了专门设置对话框的字体并将 AutoScaleMode 设置为 DPI 之外,对话框或控件没有什么特别之处。表单位于应用程序自动加载的程序集中。

我正在使用 .NET 4.7.2 和 Windows 10。

这是表单代码:

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();
        }
    }
}

这是设计器文件:

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;
    }
}

在 app.config 我根据文档设置 DpiAwareness :

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

在清单中,我正在设置兼容性:

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

所有这些都根据此处的高 DPI 支持说明进行

应用程序代码仅显示对话框:

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();
        }
    }
}

谁能看到我可能做错了什么,或者我错过了什么?

提前致谢!

4

1 回答 1

2

要遵循 Microsoft 指南并为您的应用程序提供高 DPI 支持,您应该更改几项内容。首先在您的 Designer 文件中将AutoScaleDimensions更改为AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);. 和AutoScaleModethis.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;.

在应用程序中只需使用Application.SetCompatibleTextRenderingDefault(false);

我还为设置表单的ClientSize添加了一个小更正。AdjustClientWidthToDPIScale()。根据 DPI 比例,表单的客户端宽度会根据 DPI 因子进行更改。

下面列出了所有代码。

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>

表格代码:

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);
    }
}

表单设计器

    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;
    }
}

应用代码

[STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        ValidatingSplash Splash = new ValidatingSplash();
        Splash.ShowDialog();
    }
于 2019-03-12T15:39:34.597 回答