透过将近日分辨率除以设计时分辨率来获得该因子

引言

开创响应式WinForm应用程序并不那么轻便。
响应式布局,在此小编指的是应用程序在不相同荧屏分辨率下的可用性。
对于WinForm应用程序,大家须求料定地依照分辨率来调治控件的高低和再度定位。
就算在运用WPF时有相关的施行应用,通过行使控件的docking和anchoring,或利用panels等艺术,但本文提供了壹种将响应式应用于WinForm应用程序的例外方法。

背景

自家在三个和煦统一计划的总结游戏中际遇了难题:作者设计了1台分辨率为19一陆x1080的机器,
不过当自家筹算在台式机Computer上播放时,发掘应用程序边界跑到荧屏之外。因而很有要求让程序来适应分歧分辨率的装置,而不是让用户来适应程序。
由此,笔者对代码举行了勘误。

技术

实际没什么本事可言,只是用了2个小能力。大家用多少个常量来保存设计时的显示屏分辨率,我们称为设计时分辨率。那样,无论何时运维应用程序,它都会拿走1个乘法因子,那实际上是3个比例因子,通过将最近分辨率除以设计时分辨率来收获该因子。
窗体的具有控件都被传送给这一个类对象开始展览缩放和调解大小。

代码

The Responsive Class – Responsive.cs

创建二个类Responsive.cs,增添多少个变量。

float WIDTH_AT_DESIGN_TIME = (float)Convert.ToDouble
                             (ConfigurationManager.AppSettings["DESIGN_TIME_SCREEN_WIDTH"]);
float HEIGHT_AT_DESIGN_TIME = (float)Convert.ToDouble
                              (ConfigurationManager.AppSettings["DESIGN_TIME_SCREEN_HEIGHT"]);
Rectangle Resolution;
float WidthMultiplicationFactor;
float HeightMultiplicationFactor;

规划时显示屏分辨率保存在App.config文件中。

<add key ="DESIGN_TIME_SCREEN_WIDTH" value="1920"/>
<add key ="DESIGN_TIME_SCREEN_HEIGHT" value="1080"/>

当类的1个实例被创立时,当前的解析被提须求构造函数。
之后调用该类的SetMultiplicationFactor()方法。
这种情势通过将近来分辨率除以设计时间分辨率来获得缩放因子。

public Responsive(Rectangle ResolutionParam)
{
    Resolution = ResolutionParam;
}

public void SetMultiplicationFactor()
{
    WidthMultiplicationFactor = Resolution.Width / WIDTH_AT_DESIGN_TIME;
    HeightMultiplicationFactor = Resolution.Height / HEIGHT_AT_DESIGN_TIME;
}

比如,该应用程序设计在1917×10八13分辨率。
假如此应用程序在分辨率为10贰四x76捌的Computer上运营,则WidthMultiplicationFactor和HeightMultiplicationFactor改造如下:

WidthMultiplicationFactor = 1024/1920 = 0.533
HeightMultiplicationFactor = 768/1080 = 0.711

最终有三种重载方法,它们为应用程序控件提供响应式化解方案(最好大小,地点和字体大小)的尾声方法。

public int GetMetrics(int ComponentValue)
{
    return (int)(Math.Floor(ComponentValue * WidthMultiplicationFactor));
}

public int GetMetrics(int ComponentValue, string Direction)
{
    if (Direction.Equals("Width") || Direction.Equals("Left"))
        return (int)(Math.Floor(ComponentValue * WidthMultiplicationFactor));
    else if (Direction.Equals("Height") || Direction.Equals("Top"))
        return (int)(Math.Floor(ComponentValue * HeightMultiplicationFactor));
    return 1;
}

例如说,假使存在宽度=465,中度=7二,左=36陆,最上部=四①和字体大小=40的控件,则该办法再次来到建议的尺寸,地方和字体大小为:

Width = 465 * 0.533 = 248
Height = 72 * 0.711= 51
Left = 366 * 0.533= 195
Top = 41 * 0.711= 29
Font-size = 40 * 0.533 = 21

实质上,那些方法再次来到缩放的控件与大小、地点和字体大小,而那几个值是展现的最好值。

使用 Responsive Class

小编们要求的是以别的索要响应的花样轻松地创立那些类的对象。
当前的分辨率是在构造函数中提供的, 之后的做事正是创造所需的乘法因子。

Responsive ResponsiveObj;
ResponsiveObj = new Responsive(Screen.PrimaryScreen.Bounds);
ResponsiveObj.SetMultiplicationFactor();

在那事后,表单的有所控件都将各个传递,以在表单的加载事件中调节大小和重复定位。
这么些调用在底下的代码中做到。 它所做的是首先将窗体定位到显示器的基本。
笔者在那边设置了3个校准常数(30),为最棒的垂直地点增加控件,这或然因开采职员而异。
之后,表单的每叁个控件都会再也定位,调节大小,并再次校准字体大小。

private void ResponsiveForm_Load(object sender, EventArgs e)
{
    Width = ResponsiveObj.GetMetrics(Width, "Width");           // Form width and height set up.
    Height = ResponsiveObj.GetMetrics(Height, "Height");
    Left = Screen.GetBounds(this).Width / 2 - Width / 2;        // Form centering.
    Top = Screen.GetBounds(this).Height / 2 - Height / 2 - 30;  // 30 is a calibration factor.

    foreach (Control Ctl in this.Controls)
    {
        Ctl.Font = new Font(FontFamily.GenericSansSerif, 
                   ResponsiveObj.GetMetrics((int)Ctl.Font.Size), FontStyle.Regular);
        Ctl.Width = ResponsiveObj.GetMetrics(Ctl.Width, "Width");
        Ctl.Height = ResponsiveObj.GetMetrics(Ctl.Height, "Height");
        Ctl.Top = ResponsiveObj.GetMetrics(Ctl.Top, "Top");
        Ctl.Left = ResponsiveObj.GetMetrics(Ctl.Left, "Left");
    }
}

示例

以下是二个特别轻巧的表单,个中包罗二个data
gird,3个label,多个textbox和二个button。
上边包车型大巴图纸以三种差别的分辨率截取。
下边包车型客车截图是在壹九贰零x10七十六分辨率下截取的:
图片 1

上边包车型客车截图是在1360×7七十多分辨率下截取的:
图片 2

下边包车型客车截图是在拾二4×7陆10分辨率下截取的:
图片 3

骨子里,通过裁减/扩张和另行定位控制到最棒水准,Form在区别的分辨率下看起来是一样的。

代码调度

就如大家对垂直中心定位所做的那样,大家只怕要求安装有些参数来调治总体布局。

此外,提出开荒者尝试以分歧的分辨率查看表单的外观,以确认全体的控件都以可知的,并依照预期在显示器上科学定位。

除此而外,对于3个简便的表单,那是3个通用的措施,它1旦表单的有着控件都具有那一个属性—宽度,中度,左边,顶上部分和字体大小。不过,真真实境况形并非如此。有壹部分表单控件不具有全部这一个属性。比如,图片框未有font-size属性。由此,假诺那样的景况下并未有刚毅管理,运维代码将会促成运维时极其。本文目的在于介绍这种方法,开拓职员供给依照真实情况举办校准。提议的点子如下:

private void ResponsiveForm_Load(object sender, EventArgs e)
{
    Width = ResponsiveObj.GetMetrics(Width, "Width");           // Form width and height set up.
    Height = ResponsiveObj.GetMetrics(Height, "Height");
    Left = Screen.GetBounds(this).Width / 2 - Width / 2;        // Form centering.
    Top = Screen.GetBounds(this).Height / 2 - Height / 2 - 30;  // 30 is a calibration factor.

    foreach (Control Ctl in this.Controls)
    {
        if (Ctl is PictureBox)
        {
            Ctl.Width = ResponsiveObj.GetMetrics(Ctl.Width, "Width");
            Ctl.Height = ResponsiveObj.GetMetrics(Ctl.Height, "Height");
            Ctl.Top = ResponsiveObj.GetMetrics(Ctl.Top, "Top");
            Ctl.Left = ResponsiveObj.GetMetrics(Ctl.Left, "Left");
        }
        else
        {
            Ctl.Font = new Font(FontFamily.GenericSansSerif, 
                                ResponsiveObj.GetMetrics((int)Ctl.Font.Size), FontStyle.Regular);
            Ctl.Width = ResponsiveObj.GetMetrics(Ctl.Width, "Width");
            Ctl.Height = ResponsiveObj.GetMetrics(Ctl.Height, "Height");
            Ctl.Top = ResponsiveObj.GetMetrics(Ctl.Top, "Top");
            Ctl.Left = ResponsiveObj.GetMetrics(Ctl.Left, "Left");
        }
    }
}

或是会依据业务员必要和控件的属性来调动代码。
其它,恐怕必要为分裂的控件类型引进更多的重载方法。

其他

如前所述,还有其余一些方式,例如使用WPF,使用anchoring/docking等,那是贰个更通晓的精选。
假设表单上有数千个控件,则大概会遇上加载延迟。
但是,这一点延迟对当今运作高效的管理器来讲不荒谬。
这种方法只是在表单的加载时才实行2回调用操作,由此不会带来沉重的习性下跌的主题素材。

结尾

成立响应式WinForm应用程序,依据机器的运作时刻分辨率自动调解大小,重新定位字体大小相提并论复校准字体大小,那是一种面向开拓人员的不二等秘书诀。
只需将该类加多到项目中,在App.config文件中装置规划时分辨率,然后在窗体的加载事件中加多响应代码。
So easy!

相关文章