WinForm响应式布局设计实践

作者: 游戏王朝  发布:2019-10-12

引言

开创响应式WinForm应用程序并不那么粗略。 响应式布局,在这里我指的是应用程序在不一致显示屏分辨率下的可用性。 对于WinForm应用程序,大家供给显明地依照分辨率来调度控件的轻重和另行定位。 固然在行使WPF时有相关的举办应用,通过动用控件的docking和anchoring,或行使panels等方法,但本文提供了一种将响应式应用于WinForm应用程序的两样方法。

背景

本人在二个自身布置的简便游戏中相见了难题:作者设计了一台分辨率为1918x1080的机器, 可是当笔者筹算在台式机Computer上播报时,发掘应用程序边界跑到荧屏之外。因此很有须求让程序来适应区别分辨率的设施,并非让顾客来适应程序。 由此,笔者对代码举办了创新。

技术

WinForm响应式布局设计实践。骨子里没什么技能可言,只是用了八个小技术。我们用八个常量来保存设计时的显示屏分辨率,大家称为设计时分辨率。那样,无论曾几何时运转应用程序,它都会获得四个乘法因子,那实则是叁个比重因子,通过将眼下分辨率除以设计时分辨率来赢得该因子。 窗体的富有控件都被传送给那么些类对象举行缩放和调动大小。

WinForm响应式布局设计实践。代码

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;

WinForm响应式布局设计实践。布置时显示屏分辨率保存在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!

本文由6165金沙总站发布于游戏王朝,转载请注明出处:WinForm响应式布局设计实践

关键词: