当前位置:首页 > 技术分析 > 正文内容

WinForm实现窗体自适应缩放

ruisui881个月前 (03-27)技术分析15

众所周知,WinForm采用基于像素的布局模型。

因此,原生WinForm对于窗体自适应支持不是很好

但是我们也可以通过代码来实现。

今天跟大家分享一下如何实现WinForm窗体自适应。

一、界面布局

当我们想要实现窗体自适应的时候,优先要通过界面布局设置好窗体和控件的一些属性:

1、Anchor:用于固定控件的边缘到窗体的边缘,当窗体大小改变时,控件的位置也会相应改变。

2、Dock:用于将控件停靠到窗体的边缘,控件的大小会随着窗体边缘的改变而改变。

3、布局控件:使用 TableLayoutPanel 或 FlowLayoutPanel 等布局控件可以更好地管理控件的布局,它们可以自动调整大小和位置。

4、Padding:Padding属性定义控件内部的一段空间,用于将控件的内容保持在距控件边框一定的距离。

5、Margin:Margin属性定义控件周围的空间,该空间使其他控件与控件的边框保持指定距离。

二、代码实现

除了以上方法外,在实际应用中,我们更多会使用通过代码来手动调整窗体和控件的大小和位置,这种方法第一次写的时候会麻烦一些,但是封装好之后,后续应用也比较简单。

一、我们创建一个类FormAutoSize,然后创建三个字段,分别是窗体宽度、高度和窗体对象。

public class FormAutoSize
{
    //窗体对象
    private Form form;
    //定义当前窗体的宽度
    private float width; 
    //定义当前窗体的高度
    private float height; 
}

二、在FormAutoSize类的构造方法中,初始化宽度、高度和窗体对象,同时将各个控件的宽度、高度、左边距、上边距以及字体大小,按照指定的格式(这里使用分号拼接)存储到AccessibleDescription属性里,因为AccessibleDescription属性很少使用,所以存储到这个属性里。

private void SetDescription(Control cons)
{
    foreach (Control ctl in cons.Controls)
    {
        ctl.AccessibleDescription = ctl.Width + ";" + ctl.Height + ";" + ctl.Left +
";" + ctl.Top + ";" + ctl.Font.Size;
        //递归
        if (ctl.Controls.Count > 0)
        {
            SetDescription(ctl);
        }
    }
}
public FormAutoSize(Form form)
{
    this.form = form;
    width = this.form.Width;
    height = this.form.Height;
    SetDescription(this.form);
}

三、接下来就是如何重置窗体控件布局,这里将当前的宽度高度与初始宽度高度进行相除,会得到比例系数scaleX/scaleY,然后将这个系数叠加进去,得到新的宽度高度等属性值,然后重新设置控件属性即可。

private void SetControls(float scaleX, float scaleY, Control cons)
{
    //遍历窗体中的控件,重新设置控件的值
    foreach (Control con in cons.Controls)
    {
        //获取控件的AccessibleDescription属性值,并分割后存储字符串数组
        if (con.AccessibleDescription != null)
        {
            var tag = con.AccessibleDescription.ToString().Split(';');
            //根据窗体缩放的比例确定控件的值
            con.Width = Convert.ToInt32(Convert.ToSingle(tag[0]) * scaleX); //宽度
            con.Height = Convert.ToInt32(Convert.ToSingle(tag[1]) * scaleY); //高度
            con.Left = Convert.ToInt32(Convert.ToSingle(tag[2]) * scaleX); //左边距
            con.Top = Convert.ToInt32(Convert.ToSingle(tag[3]) * scaleY); //顶边距
            var currentSize = Convert.ToSingle(tag[4]) * scaleY; //字体大小                   
            if (currentSize > 0)
            {
                con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
            }
            con.Focus();
            if (con.Controls.Count > 0)
            {
                SetControls(scaleX, scaleY, con);
            }
        }
    }
}
 /// 
 /// 重置窗体布局
 /// 
 public void ResumeLayout()
 {
     var scaleX = form.Width / width;
     var scaleY = form.Height / height;
     SetControls(scaleX, scaleY, form);
 }

四、最后一步就是如何进行调用:首先在需要进行缩放的窗体中定义一个FormAutoSize对象,然后在构造方法中实例化该对象,将当前窗体this作为参数传递进去,最后在窗体的SizeChanged事件中调用该对象的ResumeLayout方法。

private FormAutoSize formAutoSize;
public FrmMain()
{
    InitializeComponent();
    formAutoSize = new FormAutoSize(this);
    this.SizeChanged += (sender, e) =>
    {
        formAutoSize.ResumeLayout();
    };
}

五、测试效果:

缩放前尺寸:1280*720

缩放后尺寸:1420*827

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3069.html

标签: 宽度自适应
分享给朋友:

“WinForm实现窗体自适应缩放” 的相关文章

一次Java内存占用高的排查案例,解释了我对内存问题的所有疑问

问题现象7月25号,我们一服务的内存占用较高,约13G,容器总内存16G,占用约85%,触发了内存报警(阈值85%),而我们是按容器内存60%(9.6G)的比例配置的JVM堆内存。看了下其它服务,同样的堆内存配置,它们内存占用约70%~79%,此服务比其它服务内存占用稍大。那为什么此服务内存占用稍大...

《暗黑破坏神 2:重制版》PC 版 2.3 版本发布,支持英伟达 DLSS

IT之家 12 月 3 日消息,暴雪为《暗黑破坏神 2:重制版》PC 版发布了更新 2.3 版本,添加了“离线难度缩放”滑块(玩家可以在单人游戏时增加挑战和奖励的级别)、多项辅助功能和用户界面改进,以及英伟达 DLSS 支持。玩法改进:玩家现在可以在离线游戏的选项菜单中使用“游戏难度等级”,它提供与...

前端路由简介以及vue-router实现原理

作者:muwoo 来源:https://zhuanlan.zhihu.com/p/37730038后端路由简介路由这个概念最先是后端出现的。在以前用模板引擎开发页面时,经常会看到这样http://www.xxx.com/login 大致流程可以看成这样:浏览器发出请求服务器监听到80 端口(或443...

「干货」Vue+Element前端导入导出Excel

作者:xrkffgg转发链接:https://segmentfault.com/a/11900000189936191 前言1.1 业务场景由前台导入Excel表格,获取批量数据。根据一个数组导出Excel表格。2 实现原理2.1 引入工具库file-saver、xlsx、script-loader...

Vue中的路由配置常用属性

router:路由页面跳转的核心库;引入路由:import VueRouter from 'vue-router'; 注册路由:const router = new VueRouter({ })mode:模式路由有hash history两种模式:hash模式URL中包含#,#后边是...

vue开发微信小程序 - 登录组件

移动端登录功能抽象为通用组件,满足:不同移动端应用中一键登录功能复用支持多种登录:微信登录、H5、QQ登录登录组件使用//引用登录组件 import login from "../components/user/login.vue" export default { compone...