WinForm响应式布局规划实践

by admin on 2019年5月15日

引言

创办响应式WinForm应用程序并不那么粗略。
响应式布局,在此笔者指的是应用程序在差异显示器分辨率下的可用性。
对于WinForm应用程序,咱们须要了解地依照分辨率来调动控件的轻重缓急和另行定位。
就算在接纳WPF时有相关的施行应用,通过使用控件的docking和anchoring,或选取panels等艺术,但本文提供了壹种将响应式应用于WinForm应用程序的例外措施。

背景

自己在一个和好统一筹划的简短游戏中蒙受了难题:作者设计了壹台分辨率为一九一九x拾80的机器,
不过当自身妄想在笔记本Computer上海人民广播电视台播时,开掘应用程序边界跑到荧屏之外。因而很有须要让程序来适应差异分辨率的配备,而不是让用户来适应程序。
因而,笔者对代码举行了创新。

技术

事实上没什么技能可言,只是用了多少个小工夫。我们用五个常量来保存设计时的显示器分辨率,大家称为设计时分辨率。那样,无论什么时候运维应用程序,它都会博得1个乘法因子,这实在是二个比重因子,通过将眼前分辨率除以设计时分辨率来获取该因子。
窗体的全体控件都被传送给这几个类对象开始展览缩放和调节大小。

代码

亚洲必赢手机入口,The Responsive Class – Responsive.cs

创办二个类Responsive.cs,加多6个变量。

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;
}

比方,该应用程序设计在一玖贰零x拾八十分辨率。
假诺此应用程序在分辨率为拾二4×76八的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,左=36陆,顶端=4一和字体大小=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");
    }
}

示例

以下是一个特别简单的表单,在那之中含有2个data
gird,贰个label,一个textbox和一个button。
上面包车型客车图样以两种区别的分辨率截取。
下边包车型客车截图是在一玖一七x拾八十分辨率下截取的:
亚洲必赢手机入口 1

上边的截图是在1360×7陆拾陆分辨率下截取的:
亚洲必赢手机入口 2

上面包车型客车截图是在十二4×766分辨率下截取的:
亚洲必赢手机入口 3

实则,通过压缩/扩展和重复定位调控到最好水平,Form在分裂的分辨率下看起来是同样的。

代码调节

就好像大家对垂直中央定位所做的那么,大家恐怕供给设置有个别参数来调动总体布局。

其它,建议开荒者尝试以差别的分辨率查看表单的外观,以确认全体的控件都是可知的,并依据预期在显示屏上正确定位。

除却,对于四个大概的表单,那是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应用程序,依据机器的运行时刻分辨率自动调解大小,重新定位字体大小比量齐观新校准字体大小,那是1种面向开拓人士的诀窍。
只需将该类加多到项目中,在App.config文件中装置规划时分辨率,然后在窗体的加载事件中丰盛响应代码。
So easy!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图