创立响应式WinForm应用程序并不那么粗略亿万先生官方网站:

引言

创制响应式WinForm应用程序并不那么轻便。
响应式布局,在此笔者指的是应用程序在不一样屏幕分辨率下的可用性。
对于WinForm应用程序,大家须要明显地依据分辨率来调治控件的轻重和再度定位。
即便在运用WPF时有相关的试行应用,通过行使控件的docking和anchoring,或使用panels等措施,但本文提供了1种将响应式应用于WinForm应用程序的不等措施。

背景

本人在贰个友好设计的简约游戏中际遇了难题:作者布署了一台分辨率为191捌x1080的机械,
可是当自家希图在台式机Computer上广播时,开采应用程序边界跑到显示屏之外。因此很有必不可缺让程序来适应不一致分辨率的装置,而不是让用户来适应程序。
由此,作者对代码进行了改良。

技术

实质上没什么手艺可言,只是用了三个小本事。大家用多个常量来保存设计时的显示屏分辨率,大家誉为设计时分辨率。那样,无论哪天运转应用程序,它都会得到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"/>

当类的八个实例被创建时,当前的剖判被提供给构造函数。
之后调用该类的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拾七十九分辨率。
尽管此应用程序在分辨率为十二肆x768的微型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;
}

比如,要是存在宽度=4陆伍,中度=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();

在那现在,表单的具备控件都将各个传递,以在表单的加载事件中调解大小和重新定位。
那一个调用在上边包车型地铁代码中实现。 它所做的是率先将窗体定位到荧屏的着力。
小编在此间安装了一个校准常数(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个特别轻便的表单,在那之中富含1个data
gird,2个label,3个textbox和八个button。
上边包车型大巴图纸以三种区别的分辨率截取。
上边包车型客车截图是在一玖17×107柒分辨率下截取的:
亿万先生官方网站: 1

上面包车型大巴截图是在1360×767分辨率下截取的:
亿万先生官方网站: 2

下边包车型客车截图是在10二四x7陆拾伍分辨率下截取的:
亿万先生官方网站: 3

实在,通过收缩/扩大和重复定位调控到极品水准,Form在分歧的分辨率下看起来是毫无2致的。

代码调节

就如我们对垂直核心定位所做的那么,我们兴许要求设置有些参数来调动总体布局。

除此以外,建议开拓者尝试以不相同的分辨率查看表单的外观,以确认全体的控件都是可知的,并依据预期在显示屏上科学定位。

除开,对于三个简易的表单,那是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等,那是三个更了解的取舍。
假若表单上有数千个控件,则恐怕会高出加载延迟。
但是,这一点延迟对现行反革命运维高效的计算机来讲不是难题。
这种方法只是在表单的加载时才实行一遍调用操作,因而不会推动致命的特性下跌的难点。

结尾

创设响应式WinForm应用程序,遵照机器的运转时刻分辨率自动调解大小,重新定位字体大小人己一视新校准字体大小,那是一种面向开垦职员的主意。
只需将该类加多到花色中,在App.config文件中安装规划时分辨率,然后在窗体的加载事件中加上响应代码。
So easy!

相关文章

网站地图xml地图