C# Winforms自动缩放和本地化

C# Winforms自动缩放和本地化,c#,winforms,user-interface,dpi,autoscalemode,C#,Winforms,User Interface,Dpi,Autoscalemode,要使Winforms(C#)自动缩放功能正常工作,我遇到了重大问题 首先,它似乎对DPI没有任何作用。当我创建一个简单的应用程序时,所有控件在100%和125%DPI上显示相同的大小,但是我所有控件中的字体都在125%DPI下放大。我希望表单可以放大以允许更大的字体,但事实并非如此。这可能是因为应用程序不支持DPI,所以它使用XP风格的字体缩放,但我不确定。下面是它的外观: 100%DPI下的应用程序,未本地化: DPI为125%的应用程序,未本地化: 上述问题令人沮丧,但不会破坏交易。不幸

要使Winforms(C#)自动缩放功能正常工作,我遇到了重大问题

首先,它似乎对DPI没有任何作用。当我创建一个简单的应用程序时,所有控件在100%和125%DPI上显示相同的大小,但是我所有控件中的字体都在125%DPI下放大。我希望表单可以放大以允许更大的字体,但事实并非如此。这可能是因为应用程序不支持DPI,所以它使用XP风格的字体缩放,但我不确定。下面是它的外观:

100%DPI下的应用程序,未本地化:

DPI为125%的应用程序,未本地化:

上述问题令人沮丧,但不会破坏交易。不幸的是,还有另一个问题。当我的简单表单的“Localizable”属性设置为true时(因此所有控件的大小和位置都存储在
resx
文件中):

。。。RichTextBox控件变得越来越高:

在125%DPI下应用,本地化:

不幸的是,我正在开发的应用程序非常旧。它有500多个用Winforms设计的控件/对话框,因此不可能使用WPF

所以,我的问题基本上是这样的:为什么仅仅把控制位置放在
resx
文件中就会破坏125%DPI的布局?我怎样才能解决这个问题

以下是上述示例程序的源代码:

谢谢你的帮助

编辑:以下是相关来源:

表格1.cs

Form1.Designer.cs

namespace DPITest
{
部分类Form1
{
/// 
///必需的设计器变量。
/// 
private System.ComponentModel.IContainer components=null;
/// 
///清理所有正在使用的资源。
/// 
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域Windows窗体设计器生成的代码
/// 
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
/// 
私有void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager资源=新的System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.label1=new System.Windows.Forms.Label();
this.richTextBox1=new System.Windows.Forms.RichTextBox();
this.panel1=new System.Windows.Forms.Panel();
这个.SuspendLayout();
// 
//标签1
// 
resources.ApplyResources(this.label1,“label1”);
this.label1.Name=“label1”;
// 
//richTextBox1
// 
resources.ApplyResources(this.richTextBox1,“richTextBox1”);
this.richTextBox1.Name=“richTextBox1”;
// 
//小组1
// 
this.panel1.BackColor=System.Drawing.Color.Black;
resources.ApplyResources(本.panel1,“panel1”);
this.panel1.Name=“panel1”;
// 
//表格1
// 
资源。ApplyResources(此,“$this”);
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.panel1);
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.label1);
this.Name=“Form1”;
此选项为.resume布局(false);
这个。执行布局();
}
#端区
private System.Windows.Forms.label1;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.Panel panel1;
}
}
Form1.resx


text/microsoft resx
2
System.Resources.ResXResourceReader,System.Windows.Forms,版本=4.0.0.0,区域性=neutral,PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter,System.Windows.Forms,版本=4.0.0.0,区域性=neutral,PublicKeyToken=b77a5c561934e089
真的
无控制
96, 125
38, 15
8.
标签1
标签1
System.Windows.Forms.Label,System.Windows.Forms,版本=4.0.0.0,区域性=neutral,PublicKeyToken=b77a5c561934e089
美元这个
2.
15, 12
200, 110
0
richTextBox1
System.Windows.Forms.RichTextBox,System.Windows.Forms,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089
美元这个
1.
15, 121
200, 1
4.
小组1
System.Windows.Forms.Panel,System.Windows.Forms,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089
美元这个
0
真的
7, 15
232, 148
Segoe用户界面,9pt
表格1
表格1
System.Windows.Forms.Form,System.Windows.Forms,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089
Program.cs

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Thread
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace DPITest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            richTextBox1.Text = richTextBox1.Size.ToString();
        }
    }
}
namespace DPITest
{
    partial class Form1
    {
        /// <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(Form1));
            this.label1 = new System.Windows.Forms.Label();
            this.richTextBox1 = new System.Windows.Forms.RichTextBox();
            this.panel1 = new System.Windows.Forms.Panel();
            this.SuspendLayout();
            // 
            // label1
            // 
            resources.ApplyResources(this.label1, "label1");
            this.label1.Name = "label1";
            // 
            // richTextBox1
            // 
            resources.ApplyResources(this.richTextBox1, "richTextBox1");
            this.richTextBox1.Name = "richTextBox1";
            // 
            // panel1
            // 
            this.panel1.BackColor = System.Drawing.Color.Black;
            resources.ApplyResources(this.panel1, "panel1");
            this.panel1.Name = "panel1";
            // 
            // Form1
            // 
            resources.ApplyResources(this, "$this");
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.panel1);
            this.Controls.Add(this.richTextBox1);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.RichTextBox richTextBox1;
        private System.Windows.Forms.Panel panel1;

    }
}
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 

    Version 2.0

    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.

    Example:

    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>

    There are any number of "resheader" rows that contain simple 
    name/value pairs.

    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.

    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:

    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.

    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <data name="label1.AutoSize" type="System.Boolean, mscorlib">
    <value>True</value>
  </data>
  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <data name="label1.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
    <value>NoControl</value>
  </data>
  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
    <value>96, 125</value>
  </data>
  <data name="label1.Size" type="System.Drawing.Size, System.Drawing">
    <value>38, 15</value>
  </data>
  <data name="label1.TabIndex" type="System.Int32, mscorlib">
    <value>8</value>
  </data>
  <data name="label1.Text" xml:space="preserve">
    <value>label1</value>
  </data>
  <data name="&gt;&gt;label1.Name" xml:space="preserve">
    <value>label1</value>
  </data>
  <data name="&gt;&gt;label1.Type" xml:space="preserve">
    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </data>
  <data name="&gt;&gt;label1.Parent" xml:space="preserve">
    <value>$this</value>
  </data>
  <data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
    <value>2</value>
  </data>
  <data name="richTextBox1.Location" type="System.Drawing.Point, System.Drawing">
    <value>15, 12</value>
  </data>
  <data name="richTextBox1.Size" type="System.Drawing.Size, System.Drawing">
    <value>200, 110</value>
  </data>
  <data name="richTextBox1.TabIndex" type="System.Int32, mscorlib">
    <value>0</value>
  </data>
  <data name="richTextBox1.Text" xml:space="preserve">
    <value />
  </data>
  <data name="&gt;&gt;richTextBox1.Name" xml:space="preserve">
    <value>richTextBox1</value>
  </data>
  <data name="&gt;&gt;richTextBox1.Type" xml:space="preserve">
    <value>System.Windows.Forms.RichTextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </data>
  <data name="&gt;&gt;richTextBox1.Parent" xml:space="preserve">
    <value>$this</value>
  </data>
  <data name="&gt;&gt;richTextBox1.ZOrder" xml:space="preserve">
    <value>1</value>
  </data>
  <data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
    <value>15, 121</value>
  </data>
  <data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
    <value>200, 1</value>
  </data>
  <data name="panel1.TabIndex" type="System.Int32, mscorlib">
    <value>4</value>
  </data>
  <data name="&gt;&gt;panel1.Name" xml:space="preserve">
    <value>panel1</value>
  </data>
  <data name="&gt;&gt;panel1.Type" xml:space="preserve">
    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </data>
  <data name="&gt;&gt;panel1.Parent" xml:space="preserve">
    <value>$this</value>
  </data>
  <data name="&gt;&gt;panel1.ZOrder" xml:space="preserve">
    <value>0</value>
  </data>
  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
    <value>7, 15</value>
  </data>
  <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
    <value>232, 148</value>
  </data>
  <data name="$this.Font" type="System.Drawing.Font, System.Drawing">
    <value>Segoe UI, 9pt</value>
  </data>
  <data name="$this.Text" xml:space="preserve">
    <value>Form1</value>
  </data>
  <data name="&gt;&gt;$this.Name" xml:space="preserve">
    <value>Form1</value>
  </data>
  <data name="&gt;&gt;$this.Type" xml:space="preserve">
    <value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </data>
</root>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DPITest
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}