WinForm响应式布局规划推行

引言

创办响应式WinForm应用程序并不那么粗略。
响应式布局,在此小编指的是应用程序在不一样荧屏分辨率下的可用性。
对于WinForm应用程序,我们供给显著地依据分辨率来调动控件的大大小小和另行定位。
固然在采用WPF时有相关的实施应用,通过使用控件的docking和anchoring,或接纳panels等方法,但本文提供了一种将响应式应用于WinForm应用程序的不举个例子式。

背景

自身在三个团结设计的粗略游戏中相遇了难题:笔者布署了一台分辨率为一九二零x1080的机械,
但是当自家准备在台式机Computer上播放时,发现应用程序边界跑到显示器之外。由此很有不可或缺让程序来适应不相同分辨率的设备,并非让用户来适应程序。
因而,作者对代码举办了改进。

技术

实则没什么才能可言,只是用了八个小本领。我们用七个常量来保存设计时的荧屏分辨率,我们誉为设计时分辨率。那样,无论曾几何时运维应用程序,它都会获取叁个乘法因子,那实际是三个百分比因子,通过将如今分辨率除以设计时分辨率来博取该因子。
窗体的具备控件都被传送给那一个类对象进行缩放和调动大小。

代码

The Responsive Class – Responsive.cs

创办三个类Responsive.cs,增加5个变量。

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"/>

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

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

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

举例说,该应用程序设计在一九一九x1080分辨率。
假如此应用程序在分辨率为1024×768的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,高度=72,左=366,顶端=41和字体大小=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();

在那今后,表单的持有控件都将每一个传递,以在表单的加载事件中调解大小和再度定位。
这些调用在底下的代码中成就。 它所做的是率先将窗体定位到显示屏的主干。
小编在那边设置了贰个校准常数(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,三个label,贰个textbox和叁个button。
上边包车型客车图片以三种分化的分辨率截取。
上边包车型大巴截图是在一九一九x1080分辨率下截取的:
图片 1

上边的截图是在1360×768分辨率下截取的:
图片 2

上面包车型客车截图是在1024×768分辨率下截取的:
图片 3

实质上,通过压缩/扩张和重新定位调整到极品水平,Form在差异的分辨率下看起来是均等的。

代码调度

就如大家对垂直中央定位所做的那样,大家大概必要设置有些参数来调动总体布局。

另外,提议开荒者尝试以区别的分辨率查看表单的外观,以确认全数的控件都以可知的,并遵从预期在显示屏上准明显位。

除了那个之外,对于一个简便的表单,那是叁个通用的办法,它一旦表单的有所控件都有着这一个属性—宽度,中度,左边,顶上部分和字体大小。不过,真真实情状形并非那样。有一部分表单控件不具备全数这几个属性。例如,图片框未有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等,那是二个更驾驭的挑三拣四。
如若表单上有数千个控件,则也许会凌驾加载延迟。
然则,这一点延迟对现行反革命运作高效的计算机来讲小难题。
这种方法只是在表单的加载时才实施贰遍调用操作,由此不会推动致命的个性降低的标题。

结尾

制造响应式WinForm应用程序,遵照机器的运转时刻分辨率自动调度大小,重新定位字体大小并重新校准字体大小,那是一种面向开荒人士的秘诀。
只需将该类增多到花色中,在App.config文件中设置规划时分辨率,然后在窗体的加载事件中丰硕响应代码。
So easy!

相关文章

admin

网站地图xml地图