百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

WinForm实现窗体自适应缩放(winform窗口缩放)

wptr33 2025-04-11 08:29 30 浏览

众所周知,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

相关推荐

MySQL进阶五之自动读写分离mysql-proxy

自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...

Postgres vs MySQL_vs2022连接mysql数据库

...

3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?

引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...

一文由浅入深带你完全掌握MySQL的锁机制原理与应用

本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...

验证Mysql中联合索引的最左匹配原则

后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...

MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)

目录1.索引基础...

你会看 MySQL 的执行计划(EXPLAIN)吗?

SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...

MySQL 从入门到精通(四)之索引结构

索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...

mysql总结——面试中最常问到的知识点

mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...

mysql总结——面试中最常问到的知识点(2)

首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...

MySQL基础全知全解!超详细无废话!轻松上手~

本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...

深入剖析 MySQL 中的锁机制原理_mysql 锁详解

在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...

Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析

引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...

MySQL基础篇:DQL数据查询操作_mysql 查

一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...

MySql:索引的基本使用_mysql索引的使用和原理

一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...