Winforms 显示窗体和控件的缩放比例和大小

Winforms 显示窗体和控件的缩放比例和大小,winforms,Winforms,在我的桌面上,默认显示比例因子为100%。当我创建一个表单大小为400x200、图片框大小为75x23的简单应用程序时,它会按预期显示(图1) 当我在显示比例因子为125%的笔记本电脑上运行该程序时,它不会按预期显示(图2) 这种形式不合比例。现在是530x244,宽度是1.33x400,高度是1.22x200 红色的图片盒也不符合比例,它是100x28。水平尺寸为1.33x75,垂直尺寸为1.25x23 绿色和蓝色图片框的大小在代码中设置 public Form1() { Initia

在我的桌面上,默认显示比例因子为100%。当我创建一个表单大小为400x200、图片框大小为75x23的简单应用程序时,它会按预期显示(图1)

当我在显示比例因子为125%的笔记本电脑上运行该程序时,它不会按预期显示(图2)

这种形式不合比例。现在是530x244,宽度是1.33x400,高度是1.22x200

红色的图片盒也不符合比例,它是100x28。水平尺寸为1.33x75,垂直尺寸为1.25x23

绿色和蓝色图片框的大小在代码中设置

public Form1()
{
  InitializeComponent();

  double factor = CreateGraphics().DpiX / 96f;
  pictureBox2.Size = new Size((int)(75 * factor), (int)(23 * factor));

  pictureBox3.Size = new Size(75, 23);


  label1.Text = String.Format("Form:{0}-{1}  DpiX:{2}  DpiY:{3}",
    this.Size.Width,
    this.Size.Height,
    CreateGraphics().DpiX,
    CreateGraphics().DpiY
    );

  label2.Text = String.Format("{0}-{1}", pictureBox1.Size.Width, pictureBox1.Size.Height);
  label3.Text = String.Format("{0}-{1}", pictureBox2.Size.Width, pictureBox2.Size.Height);
  label4.Text = String.Format("{0}-{1}", pictureBox3.Size.Width, pictureBox3.Size.Height);
}
表单和picturebox最初在InitializeComponent函数中调整大小

          private void InitializeComponent()
{
  this.label1 = new System.Windows.Forms.Label();
  this.pictureBox1 = new System.Windows.Forms.PictureBox();
  this.pictureBox2 = new System.Windows.Forms.PictureBox();
  this.pictureBox3 = new System.Windows.Forms.PictureBox();
  this.label2 = new System.Windows.Forms.Label();
  this.label3 = new System.Windows.Forms.Label();
  this.label4 = new System.Windows.Forms.Label();
  ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
  ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
  ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
  this.SuspendLayout();
  // 
  // label1
  // 
  this.label1.AutoSize = true;
  this.label1.Location = new System.Drawing.Point(12, 9);
  this.label1.Name = "label1";
  this.label1.Size = new System.Drawing.Size(35, 13);
  this.label1.TabIndex = 0;
  this.label1.Text = "label1";
  // 
  // pictureBox1
  // 
  this.pictureBox1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192)))));
  this.pictureBox1.Location = new System.Drawing.Point(14, 32);
  this.pictureBox1.Name = "pictureBox1";
  this.pictureBox1.Size = new System.Drawing.Size(75, 23);
  this.pictureBox1.TabIndex = 8;
  this.pictureBox1.TabStop = false;
  // 
  // pictureBox2
  // 
  this.pictureBox2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
  this.pictureBox2.Location = new System.Drawing.Point(14, 61);
  this.pictureBox2.Name = "pictureBox2";
  this.pictureBox2.Size = new System.Drawing.Size(75, 23);
  this.pictureBox2.TabIndex = 11;
  this.pictureBox2.TabStop = false;
  // 
  // pictureBox3
  // 
  this.pictureBox3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
  this.pictureBox3.Location = new System.Drawing.Point(14, 90);
  this.pictureBox3.Name = "pictureBox3";
  this.pictureBox3.Size = new System.Drawing.Size(75, 23);
  this.pictureBox3.TabIndex = 15;
  this.pictureBox3.TabStop = false;
  // 
  // label2
  // 
  this.label2.AutoSize = true;
  this.label2.Location = new System.Drawing.Point(96, 41);
  this.label2.Name = "label2";
  this.label2.Size = new System.Drawing.Size(35, 13);
  this.label2.TabIndex = 16;
  this.label2.Text = "label2";
  // 
  // label3
  // 
  this.label3.AutoSize = true;
  this.label3.Location = new System.Drawing.Point(96, 71);
  this.label3.Name = "label3";
  this.label3.Size = new System.Drawing.Size(35, 13);
  this.label3.TabIndex = 17;
  this.label3.Text = "label3";
  // 
  // label4
  // 
  this.label4.AutoSize = true;
  this.label4.Location = new System.Drawing.Point(96, 100);
  this.label4.Name = "label4";
  this.label4.Size = new System.Drawing.Size(35, 13);
  this.label4.TabIndex = 18;
  this.label4.Text = "label4";
  // 
  // Form1
  // 
  this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  this.AutoScroll = true;
  this.ClientSize = new System.Drawing.Size(384, 162);
  this.Controls.Add(this.label4);
  this.Controls.Add(this.label3);
  this.Controls.Add(this.label2);
  this.Controls.Add(this.pictureBox3);
  this.Controls.Add(this.pictureBox2);
  this.Controls.Add(this.pictureBox1);
  this.Controls.Add(this.label1);
  this.Name = "Form1";
  this.Text = "Form1";
  ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
  ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
  ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).EndInit();
  this.ResumeLayout(false);
  this.PerformLayout();

}

#endregion

private System.Windows.Forms.Label label1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.PictureBox pictureBox3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
}

当缩放设置为100%时,DpiX将为96f。当设置为125%时,DpiX将为120f。 绿色图片框使用缩放因子,大小为93x28,如预期(75*120/96=93和23*120/96=28)。蓝色图片框显示75x23的原始尺寸,以供参考


有人能帮我解释一下为什么表格和红色图片框超出了设计比例吗?如何解释1.33和1.22这两个因素?

我想我已经找到了答案。将表单属性“AutoScaleMode”从“Font”更改为“Dpi”可以实现这一目的

编辑:注意Hans的答案,Dpi设置可能会有一些副作用


(似乎我需要10个信誉点来显示图像)

我想我找到了答案。将表单属性“AutoScaleMode”从“Font”更改为“Dpi”可以实现这一目的

编辑:注意Hans的答案,Dpi设置可能会有一些副作用

(似乎我需要10个信誉点来显示图像)

这是一个明智的选择。注意AutoScaleMode属性的备选选项,您也可以选择AutoScaleMode.Dpi。这就是你所希望的

但事实并非如此,表单和pictureBox1的自动缩放是基于AutoScaleMode.Font的。很难看到的是,如果仔细观察,你会发现,在第二个屏幕截图中,你没有得到相同的字体。默认设置为“Microsoft Sans Serif”,它在较新的Windows版本上失效,您可以获得替代设置。应该是塞戈。Windows的一部分机制,使旧的UI设计在新的操作系统版本上看起来新鲜。请注意它的平均字符宽度是如何高出一点的。它补偿了这一点,这就是为什么你得到的是1.33而不是1.25

你可以选择AutoScaleMode.Dpi,然后你会得到你喜欢的数字。但冒着文本不再适合控制的风险。考虑使用两种机器上可用的字体,如TaHOMA.

使其更具可预测性。 得到1.22是因为表单自动缩放其ClientSize属性,而不是大小。边框大小相同,因此总体大小增加小于1.25。如果用户修改主题以显示更大的标题文本和按钮,可能会有更大的不同。只有ClientSize很重要,这是确保窗口内容适合的重要属性

请注意使用CreateGraphics(),它有太多的副作用。此方法只能通过首先创建本机窗口来工作。这会导致自动缩放生效,比正常情况下要早得多。因此,您正在修改已重新缩放的大小,这大大增加了混乱。这里更安全的版本是
Graphics.FromHwnd(IntPtr.Zero)
,现在您可以使用原始设计指标修改尺寸,至少直到加载事件触发为止

这是一个明智的选择。注意AutoScaleMode属性的备选选项,您也可以选择AutoScaleMode.Dpi。这就是你所希望的

但事实并非如此,表单和pictureBox1的自动缩放是基于AutoScaleMode.Font的。很难看到的是,如果仔细观察,你会发现,在第二个屏幕截图中,你没有得到相同的字体。默认设置为“Microsoft Sans Serif”,它在较新的Windows版本上失效,您可以获得替代设置。应该是塞戈。Windows的一部分机制,使旧的UI设计在新的操作系统版本上看起来新鲜。请注意它的平均字符宽度是如何高出一点的。它补偿了这一点,这就是为什么你得到的是1.33而不是1.25

你可以选择AutoScaleMode.Dpi,然后你会得到你喜欢的数字。但冒着文本不再适合控制的风险。考虑使用两种机器上可用的字体,如TaHOMA.

使其更具可预测性。 得到1.22是因为表单自动缩放其ClientSize属性,而不是大小。边框大小相同,因此总体大小增加小于1.25。如果用户修改主题以显示更大的标题文本和按钮,可能会有更大的不同。只有ClientSize很重要,这是确保窗口内容适合的重要属性


请注意使用CreateGraphics(),它有太多的副作用。此方法只能通过首先创建本机窗口来工作。这会导致自动缩放生效,比正常情况下要早得多。因此,您正在修改已重新缩放的大小,这大大增加了混乱。这里更安全的版本是
图形。从hwnd(IntPtr.Zero)
,现在您可以使用原始设计指标修补大小,至少直到加载事件触发为止。

所有代码都是现在发布的,只是一个设置图片框大小和设置标签文本的构造函数。当windows显示比例设置为100%时,Dpi为96。要知道比例因子(新的)Dpi必须偏离96。这是一个有用的网站,但我没有在这里找到答案。好的,我可以重现你的问题。更奇怪的是:当我将缩放比例设置为150%时,DpiX返回96!我也注意到了这一点,这与显示器的最大分辨率有关,它无法处理
 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;