WinForms 不同 DPI 布局

4
一些通过Visual Studio和设计器创建的表单和控件具有根据Windows当前DPI /字体大小自动缩放的能力。我的UI的一部分是一个选项卡控件,其中包含根据用户选择生成的动态页面、标签和输入框。当这些控件被创建时,它们使用硬编码的尺寸,看起来适合96 DPI。
在.Net中是否有一种自动的方法可以对这些生成的控件进行相同的调整大小操作,就像设计器生成的控件一样?我想避免自己缩放控件,因为这是旧代码,不易于维护。
3个回答

10

从技术上讲,通过迭代选项卡页面的控件集合,并将点和大小属性乘以缩放因子是很容易做到的。但是一旦考虑到停靠和锚定属性,这就变得非常棘手。

到目前为止,最简单的方法是让Form类的缩放机制替您完成此工作。 您需要在Load事件运行之前将控件添加到选项卡页中。 在构造函数中执行此操作。

快速提示:为避免切换DPI设置来测试代码的痛苦,请在表单构造函数中添加以下内容以调用重新缩放逻辑:

protected override void OnLoad(EventArgs e) {
    this.Font = new Font(this.Font.FontFamily, this.Font.Size * 120 / 96);
    base.OnLoad(e);
}

@nobugz:假设有各种不同类型的选项卡页(每种类型都有不同的内部控件):这些是否可以预定义为UserControl,以获得“窗体类缩放机制”的相同好处?因此,在运行时,如果用户创建了一个新的类型#3的选项卡页:则新选项卡页的Controls集合将设置为UserControl3的新实例,该实例停靠在“fill”位置,当然会调用UserControl的“Load”事件:在这种情况下,UserControl也会适当地缩放吗?谢谢。 - BillW
2
是的,缩放是由ContainerControl实现的。就像Form一样,UserControl也从它派生。 - Hans Passant
@nobuz 谢谢,我从你的回答中学到的信息以及确认同样适用于用户控件非常有价值! - BillW

1

我解决了同样的问题,通过根据需要在运行时创建控件,并执行designer.cs所做的操作:

void CreateRuntimePanel()
{
    //instantiate controls here...

    //suspend layouts
    //begin inits

    this.SuspendLayout();

    //set control properties here

    //before adding any control to form's Controls collection, do this
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

    //add controls to form's Controls collection here

    //resume layouts
    //end inits

    this.ResumeLayout(false);  
}

0

是的,AutoScaleMode能够使我的其他控件完美缩放,但它似乎并不影响动态控件。我还在生成控件时模仿了设计器使用的Suspend/ResumeLayout和PerformLayout调用。 - WhoaNow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接