WinForm响应式布局设计实践

2019-10-11 19:58栏目:吸血莱恩2游戏
TAG:

引言

创办响应式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分辨率。 假若此应用程序在分辨率为1024x768的微型计算机上运行,则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

上边包车型客车截图是在1360x768分辨率下截取的:
图片 2

上边包车型大巴截图是在1024x768分辨率下截取的:
图片 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!

版权声明:本文由金莎国际发布于吸血莱恩2游戏,转载请注明出处:WinForm响应式布局设计实践