记录|C# winform布局学习

news2024/9/20 9:04:00

目录

  • 前言
  • 一、自适应布局
    • Step1. 添加AutoAdaptWindowsSize类
    • Step2. Form中引用
    • Step3. 创建SizeChanged事件函数
    • Step4. 在Fram.Disiger中添加
  • 更新时间

前言

参考视频:
C#5分钟winform快速自适应布局
参考文章:
其他参考:

写这篇文章,主要是我发现自己的界面太丑了,我受不了。而且项目运行后,winform窗口是窗口,放大后又是另一种样子,丑到家了。
在这里插入图片描述


一、自适应布局

以下内容的原版在这:C#快速自适应布局
下面的代码是根据我实际写的界面进行更改了的。

Step1. 添加AutoAdaptWindowsSize类

  • 做法:将Form装入Panel容器中。在项目中添加AutoAdaptWindowsSize.cs类。代码见下图【直接复制类中内容即可,添加的类名重命名为AutoAdaptWindowsSize.cs】
  • 优点:不用在Form中添加任何布局,直接将类复制到项目中,在Form代码中调用即可,页面大小会自动计算,修改方便,速度块。
  • 缺点:Form中的背景图片会直接显示成纯图的背景。【AutoAdaptWindowsSize类中会创建一个Panel,Panel背景会自动设置,而Pannel的纯色背景会覆盖掉Form的背景。】

背景问题解决方案:给Pannel的背景色改为透明(Transparent)。如 Panel.BackColor = Color.TransParents

    internal class AutoAdaptWindowsSize
    {
        double formOriginalWidth;//窗体高度原始宽度
        double formOriginalHeight;//窗体原始
        double scaleX;//水平缩放比例
        double scaleY;//垂直缩放比例
        Dictionary<string, string> ControlsInfo = new Dictionary<string, string>();//控件中心Left,Top,控件Width,控件Height,控件字体Size

        private Form _form;
        Panel Win_Panel1 = new Panel();
        public AutoAdaptWindowsSize(Form form)
        {
            _form = form;

            //代码生成一个容器panel1,添加至窗体
            _form.Controls.Add(Win_Panel1);
            Win_Panel1.BorderStyle = BorderStyle.None;    //容器border样式
            Win_Panel1.Dock = DockStyle.Fill;             //设置填充,下面添加控件至容器完成后,容器会填充窗口
            Win_Panel1.BackColor = Color.Transparent;    // 这里默认的背景颜色是form的背景颜色,如果form页面时图片,需要将这里的颜色设置成透明,否则会被覆盖。
            //将窗体所有控件添加至panel1
            while (_form.Controls[0].Name.Trim() != "")
            {
                foreach (Control item in _form.Controls)
                {

                    if (item.Name.Trim() != "" && item.Name.Trim() != Win_Panel1.Name.Trim())
                    {
                        Win_Panel1.Controls.Add(item);
                    }
                }
            }

            //保存窗体和控件初始大小
            InitControlsInfo(Win_Panel1);
        }

        public void InitControlsInfo(Control ctrlContainer)
        {
            if (ctrlContainer.Parent == _form)//获取窗体的高度和宽度
            {
                formOriginalWidth = Convert.ToDouble(ctrlContainer.Width);
                formOriginalHeight = Convert.ToDouble(ctrlContainer.Height);
            }
            foreach (Control item in ctrlContainer.Controls)
            {
                if (item.Name.Trim() != "")
                {
                    //添加信息:键值:控件名,内容:据左边距离,距顶部距离,控件宽度,控件高度,控件字体。
                    ControlsInfo.Add(item.Name, (item.Left + item.Width / 2) + "," + (item.Top + item.Height / 2) + "," + item.Width + "," + item.Height + "," + item.Font.Size);
                }
                if ((item as UserControl) == null && item.Controls.Count > 0)
                {
                    InitControlsInfo(item);
                }
            }

        }
        public void FormSizeChanged()
        {
            try
            {
                if (ControlsInfo.Count > 0)//如果字典中有数据,即窗体改变
                {
                    ControlsZoomScale(Win_Panel1);//表示pannel控件
                    ControlsChange(Win_Panel1);
                }
            }
            catch { }
        }
        private void ControlsZoomScale(Control ctrlContainer)
        {
            scaleX = (Convert.ToDouble(ctrlContainer.Width) / formOriginalWidth);
            scaleY = (Convert.ToDouble(ctrlContainer.Height) / formOriginalHeight);
        }

        /// <summary>
        /// 改变控件大小
        /// </summary>
        /// <param name="ctrlContainer"></param>

        private void ControlsChange(Control ctrlContainer)
        {
            double[] pos = new double[5];//pos数组保存当前控件中心Left,Top,控件Width,控件Height,控件字体Size
            foreach (Control item in ctrlContainer.Controls)//遍历控件
            {
                if (item.Name.Trim() != "")//如果控件名不是空,则执行
                {
                    if ((item as UserControl) == null && item.Controls.Count > 0)//如果不是自定义控件
                    {
                        ControlsChange(item);//循环执行
                    }
                    string[] strs = ControlsInfo[item.Name].Split(',');//从字典中查出的数据,以‘,’分割成字符串组

                    for (int i = 0; i < 5; i++)
                    {
                        pos[i] = Convert.ToDouble(strs[i]);//添加到临时数组
                    }
                    double itemWidth = pos[2] * scaleX;     //计算控件宽度,double类型
                    double itemHeight = pos[3] * scaleY;    //计算控件高度
                    item.Left = Convert.ToInt32(pos[0] * scaleX - itemWidth / 2);//计算控件距离左边距离
                    item.Top = Convert.ToInt32(pos[1] * scaleY - itemHeight / 2);//计算控件距离顶部距离
                    item.Width = Convert.ToInt32(itemWidth);//控件宽度,int类型
                    item.Height = Convert.ToInt32(itemHeight);//控件高度
                    if (float.Parse((pos[4] * Math.Min(scaleX, scaleY)).ToString()) != 0)         //缩放字体大小不能为0
                    { item.Font = new Font(item.Font.Name, float.Parse((pos[4] * Math.Min(scaleX, scaleY)).ToString())); }  //字体
                }
            }
        }
    }

Step2. Form中引用

引用:【这个是因为我将AutoAdaptWindowsSize.cs放在Manager文件夹下了】

using thinger.ProjectDemo.Manager;

在这里插入图片描述

创建全局变量

		AutoAdaptWindowsSize AutoSize; 

在Form_Load添加如下代码,在界面初始化的过程中创建AutoSize。

        private void FrmMain_Load(object sender, EventArgs e)
        {
            autoSize = new AutoAdaptWindowsSize(this);
        }

Step3. 创建SizeChanged事件函数

        private void FrmMain_SizeChanged(object sender, EventArgs e)
        {
            if (autoSize != null) // 这个判断防止电脑缩放的布局不是100%时候的报错。
            {
                autoSize.FormSizeChanged();
            }
        }

Step4. 在Fram.Disiger中添加

为了解决拖动窗口时出现的严重闪屏现象。Disiger位置:
在这里插入图片描述
代码如下:

using System.Windows.Forms;

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

更新时间

  • 2024.07.19

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1937504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python学习】python的知识点总结、特点和思考及解答(代码示例)

引言 python 是一种高级编程语言&#xff0c;具有简洁的语法和丰富的库&#xff0c;被广泛应用于Web开发、数据分析、人工智能、科学计算等领域 文章目录 引言一、python知识点总结1.1 基础语法1.1.1 变量和数据类型1.1.2 控制结构1.1.3 函数和模块 1.2 面向对象编程1.2.1 类和…

vue的三大核心知识点

响应式&#xff1a; 监听data属性getter setter(包括数组)模板编译&#xff1a; 模板到render函数再到vnodevdom&#xff1a; patch(elem, vnode)和patch(vnode, newVnode) vue组件初次渲染过程 解析模板为render函数&#xff08;或在开发环境已完成&#xff0c;vue-loader&a…

Vue 对接海康威视,实现摄像头画面展示

文章目录 需求分析1. 下载2. 安装3. new 一个WebControl 插件相关实例 需求 项目中集成海康威视&#xff0c;实现摄像头画面展示 分析 1. 下载 传送门&#xff1a;官方插件包和文档下载 2. 安装 &#xff08;1&#xff09;下载完成后打开 &#xff08;2&#xff09;在项…

三款知名的基于RAG技术的智能体平台分析

这篇文章是关于目前市面上三款知名的基于检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;技术的智能体平台的详细对比分析。这三款产品分别是FastGPT、Dify和Coze。文章从不同维度分析了这些产品的优势和劣势&#xff0c;以供读者参考。 什么是RAG&…

【Qt之·类QRandomGenerator】

系列文章目录 文章目录 前言一、概述1.2. 二、实例演示总结 前言 一、概述 1. 2. 二、实例演示 示例1&#xff1a; #include <QRandomGenerator> #include <QRandomGenerator64> #include <QDebug>int randomInt QRandomGenerator::global()->bound…

ESP8266模块(2)

实例1 查看附近的WiFi 步骤1&#xff1a;进入AT指令模式 使用USB转串口适配器将ESP8266模块连接到电脑。打开串口终端软件&#xff0c;并设置正确的串口和波特率&#xff08;通常为115200&#xff09;。输入以下命令并按回车确认&#xff1a; AT如果模块响应OK&#xff0c;…

TCP状态转换详解

1.什么是TCP的状态转换 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层协议。在 TCP 连接的生命周期中&#xff0c;连接的状态会随着不同阶段的通信而发生变化&#xff0c;这些变化被称为状…

数据库最佳实践:优化爬虫管理的数据存储方案

摘要&#xff1a; 面对日益增长的数据抓取需求&#xff0c;如何高效管理和存储爬虫获取的海量信息成为一大挑战。本文将深入探讨数据库最佳实践&#xff0c;揭示如何通过优化策略提升爬虫数据存储效率&#xff0c;助您跨越数据管理的障碍&#xff0c;实现数据价值最大化。 一、…

虚拟试衣人像合成新SOTA!IMAGDressing-v1:ControlNet和IP-Adapter的最佳拍档

文章链接&#xff1a;https://arxiv.org/pdf/2407.12705 github链接&#xff1a;https://imagdressing.github.io/ Demo试用&#xff1a;https://sf.dictdoc.site/ 亮点直击 为商家引入了一项新的虚拟试衣&#xff08;VD&#xff09;任务&#xff0c;并设计了一个综合亲和力测量…

关闭 Linux 服务器上的 IPv6

虽然 IPv6 已经逐渐普及&#xff0c;但在某些 Linux 服务器上的业务系统仍然可能遇到一些奇怪的问题。特别是在集群场景中&#xff0c;因为集群各个节点之间需要互相通信&#xff0c;如果 IPv6 没有正确配置网络&#xff0c;可能导致一些未知问题&#xff0c;解决起来相当麻烦。…

acwing796-子矩阵的和-前缀和

s矩阵是全局变量&#xff0c;维度n*m,从1~n和 1~m存储元素【0】【0】~【0】【m】和【0】【0】~【n】【0】分别存储的都是0.s矩阵刚开始是存储输入的元素&#xff0c;后面用于存储前缀和。 s矩阵的意思是s【i】【j】表示从【0】【0】到【i】【j】为对角线的矩阵里面所有元素的和…

Pytorch的编译新特性TorchDynamo的工作原理和使用示例

在深度学习中&#xff0c;优化模型性能至关重要&#xff0c;特别是对于需要快速执行和实时推断的应用。而PyTorch在平衡动态图执行与高性能方面常常面临挑战。传统的PyTorch优化技术在处理动态计算图时效果有限&#xff0c;导致训练时间延长和模型性能不佳。TorchDynamo是一种为…

AI批量剪辑,批量发布大模型矩阵系统搭建开发

目录 前言 一、AI矩阵系统功能 二、AI批量剪辑可以解决什么问题&#xff1f; 总结&#xff1a; 前言 基于ai生成或剪辑视频的原理&#xff0c;利用ai将原视频进行混剪&#xff0c;生成新的视频素材。ai会将剪辑好的视频加上标题&#xff0c;批量发布到各个自媒体账号上。这…

[CP_AUTOSAR]_通信服务_CanTp模块(二)

目录 3、功能规范3.1、提供给上层的服务3.1.1、Initialization and shutdown3.1.2、Transmit request3.1.3、Transmit cancellation 3.2、提供给下层的服务3.2.1、Transmit confirmation3.2.2、Reception indication 3.3、内部行为3.3.1、N-SDU接收 在前面 《[CP_AUTOSAR]_通信…

一款异次元小清新风格的响应式wordpress个人博客主题

一款异次元小清新风格的响应式个人博客主题。这是一款专注于用户阅读体验的响应式 WordPress 主题&#xff0c;整体布局简洁大方&#xff0c;针对资源加载进行了优化。 Kratos主题基于Bootstrap和Font Awesome的WordPress一个干净&#xff0c;简单且响应迅速的博客主题&#x…

go-微服务的设计概括

一、微服务到底是什么&#xff1f; 初学者很容易把微服务和分布式混为一谈&#xff0c;但其实二者之间存在非常大的差异&#xff0c;我个人认为主要有以下几点&#xff1a; 分布式主要是一种技术手段&#xff0c;用来保证多个相同的进程能够共同工作而不出错。采用各种复杂的…

修复公路 (最小生成树)

//新生训练 Input 4 4 1 2 6 1 3 4 1 4 5 4 2 3 Output 5 #include <iostream> #include <algorithm> #include <bits/stdc.h> using namespace std; typedef long long ll;struct road {int u,v;ll w;bool operator<(const road a)const{return w<a.w…

每日练习*

目录 一、选择题二、知识点1.中间件特点的描述1.1中间件的定义和作用1.2中间件的主要特点1.3中间件的应用场景1.4中间件的发展趋势 二、重写与重载总结![](https://i-blog.csdnimg.cn/direct/aa4190dfbd0e463294e41059016b8895.png) 一、选择题 题目选自牛客网 1.执行下列代码…

自动化测试 - selenium 环境搭建

在进行自动化测试时&#xff0c;Selenium 是一个非常强大的工具&#xff0c;在使用前需要做一些环境准备。 1. 配置 Chromedriver 访问 Chrome 浏览器的官方网站&#xff08;https://www.google.cn/chrome/&#xff09;&#xff0c;下载并安装 Chrome 浏览器。 接下来&#x…

Postman 集合变量的实用指南

在运用 Postman 进行 API 测试时&#xff0c;变量扮演着动态数据存储器的角色。它们作为键值对存在&#xff0c;其中“键”是变量的标识&#xff0c;而“值”则是存储在变量中的数据。这种机制不仅可以在多个 API 调用中重用数据&#xff0c;还有助于降低数据冗余&#xff0c;优…