Winforms 更改应用程序中所有控件的字体大小(win窗体)

Winforms 更改应用程序中所有控件的字体大小(win窗体),winforms,fonts,resolution,adaptive-design,adaptive-ui,Winforms,Fonts,Resolution,Adaptive Design,Adaptive Ui,我有一个应用程序,需要适应一系列不同的屏幕大小(分辨率)。 我用表格布局面板完成了大部分工作 但是有些控件(大多数是按钮和标签)字体太大,文本不适合控件。 到目前为止,我已经通过使用 if (Screen.PrimaryScreen.Bounds.Width < 1440) { button_5.Font = new Font("Impact", button_5.Font.Size - 4); } if(S

我有一个应用程序,需要适应一系列不同的屏幕大小(分辨率)。 我用表格布局面板完成了大部分工作

但是有些控件(大多数是按钮和标签)字体太大,文本不适合控件。 到目前为止,我已经通过使用

            if (Screen.PrimaryScreen.Bounds.Width < 1440)
        {
            button_5.Font = new Font("Impact", button_5.Font.Size - 4);
        }
if(Screen.PrimaryScreen.Bounds.Width<1440)
{
button_5.Font=新字体(“影响”,button_5.Font.Size-4);
}
但是,对于应用程序中的每个控件来说,添加的文本太多了

是否有一种方法可以一次更改应用程序上所有控件的字体?
或者至少是表单上的所有控件?

一个简单的递归函数将遍历表单中的所有控件并更改字体大小。您需要根据控件对其进行测试并查看效果,因为在这段代码中没有异常处理

public void SetAllControlsFont(ControlCollection ctrls)
{
    foreach(Control ctrl in ctrls)
    {
        if(ctrl.Controls != null)
            SetAllControlsFont(ctrl.Controls);

        ctrl.Font = new Font("Impact", ctrl.Font.Size - 4);

    }
}
您可以通过初始表单的控件集合从顶级表单调用它

SetAllControlsFont(this.Controls);
基于良好的回答,我将做以下改进:

/// <summary>
/// Changes fonts of controls contained in font collection recursively. <br/>
/// <b>Usage:</b> <c><br/>
/// SetAllControlsFont(this.Controls, 20); // This makes fonts 20% bigger. <br/>
/// SetAllControlsFont(this.Controls, -4, false); // This makes fonts smaller by 4.</c>
/// </summary>
/// <param name="ctrls">Control collection containing controls</param>
/// <param name="amount">Amount to change: posive value makes it bigger, 
/// negative value smaller</param>
/// <param name="amountInPercent">True - grow / shrink in percent, 
/// False - grow / shrink absolute</param>
public static void SetAllControlsFontSize(
                   System.Windows.Forms.Control.ControlCollection ctrls,
                   int amount = 0, bool amountInPercent = true)
{
    if (amount == 0) return;
    foreach (Control ctrl in ctrls)
    {
        // recursive
        if (ctrl.Controls != null) SetAllControlsFontSize(ctrl.Controls,
                                                          amount, amountInPercent);
        if (ctrl != null)
        {
            var oldSize = ctrl.Font.Size;
            float newSize = 
               (amountInPercent) ? oldSize + oldSize * (amount / 100) : oldSize + amount;
            if (newSize < 4) newSize = 4; // don't allow less than 4
            var fontFamilyName = ctrl.Font.FontFamily.Name;
            ctrl.Font = new Font(fontFamilyName, newSize);
        };
    };
}
或者您可以将字体大小绝对缩小到-4,如:

SetAllControlsFont(this.Controls, amount: -4, amountInPercent: false); 
在这两个示例中,所有字体都将受到更改的影响。您不需要知道字体系列名称,每个控件可以有不同的名称

相结合,您可以根据Windows设置在应用程序中自动缩放字体(如果您右键单击桌面,然后选择“显示设置”、“缩放和布局”并修改“更改文本、应用程序和其他项目的大小”的值,您可以找到这些设置)-在比build 1809更新的Windows 10版本中,这(重新)命名为:

您还应根据表单布局将大小限制在某个最大/最小值,例如:

if (percentage > 80)  percentage = 80;
if (percentage < -20) percentage = -20;
if(百分比>80)百分比=80;
如果(百分比<-20)百分比=-20;

同样,绝对值也是如此-请注意,在代码中已经设置了一个限制:实际上,字体不能小于4em-这被设置为最小限制(当然您可以根据需要进行调整)。

每个表单都是一个控件容器,其中Controls属性列出该表单上的所有控件。当控件本身是控件容器(面板、groupbox)时,它具有一个控件集合,其中包含由该容器承载的控件。构建一个递归函数来循环表单中的所有控件相对容易。您能否给我一个这样一个函数的例子,这样我就可以构建我所需要的?我已经通过使用foreach(tableLayoutPanel1.controls中的Control ctrl)设置了表布局面板中所有控件的字体{ctrl.Font=新字体(“Impact”,ctrl.Font.Size-4);}但是还不知道如何访问整个表单的所有控件。这只会更改第一个表布局面板的字体,但不会循环遍历其余控件。如果.controls是表单.controls集合,则不应该是这种情况。层次结构的顶层它可能与
this.Co这一事实有关吗控件
仅包含
{System.Windows.Forms.TableLayoutPanel,BorderStyle:System.Windows.Forms.BorderStyle.None}
它甚至不是窗体上的实际控件,只是控件的类型。我通过更改
public void SetAllControlsFont(ControlCollection ctrls)使其工作
public void SetAllControlsFont(Control.ControlCollection ctrls)
而不是这个。控件我给了它tableLayoutPanel1.Controls,它包含所有其他表格布局面板。现在它在所有面板和这些面板内的所有控件之间循环。问题是
SetAllControlsFont(ctrl.Controls);
无法从Cntrol.ControlCollection转换为Form.ControlCollection。显然,这些是不同的控件集合类型。
var percentage = GetWindowsScaling() - 100;
SetAllControlsFont(this.Controls, percentage); 
if (percentage > 80)  percentage = 80;
if (percentage < -20) percentage = -20;