记录|C# winform布局学习

目录

  • 前言
  • 一、自适应布局
    • 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,控件字体Sizeprivate 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页面时图片,需要将这里的颜色设置成透明,否则会被覆盖。//将窗体所有控件添加至panel1while (_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,控件字体Sizeforeach (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.mzph.cn/diannao/48205.shtml

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

相关文章

在 Java 中,怎样设计一个可扩展且易于维护的微服务架构?

在Java中设计一个可扩展且易于维护的微服务架构&#xff0c;可以考虑以下几个方面&#xff1a; 模块化设计&#xff1a;将应用拆分为多个小的、独立的模块&#xff0c;每个模块负责处理特定的业务逻辑。每个模块可以独立开发、测试和部署&#xff0c;增加或替换模块时不会影响其…

AI学习指南机器学习篇-t-分布领域嵌入(t-Distributed Stochastic Neighbor Embedding,t-SNE)简介

AI学习指南机器学习篇-t-分布领域嵌入&#xff08;t-Distributed Stochastic Neighbor Embedding&#xff0c;t-SNE&#xff09;简介 导言 在机器学习中&#xff0c;高维数据的降维和可视化一直是一个重要的问题。高维数据往往难以理解和分析&#xff0c;而且直接在高维空间中…

C#知识|账号管理系统-修改账号按钮功能的实现

哈喽,你好啊,我是雷工! 前边学习了通过选择条件查询账号的功能: 《提交查询按钮事件的编写》 本节继续学习练习C#,今天练习修改账号的功能实现。 以下为学习笔记。 01 实现功能 ①:从查询到的账号中,选择某一账号,然后点击【修改账号】按钮,将选中的信息获取显示到…

Java多线程-----线程安全问题(详解)

目录 &#x1f347;一.线程安全问题的引入&#xff1a; &#x1f352;二.线程安全问题产生的原因&#xff1a; &#x1f34c;三.如何解决线程安全问题&#xff1a; &#x1f389;1.synchronized关键字: &#x1f989;sychronized关键字的特性: ✨2.volatile关键字: &#…

橙芯创想:香橙派AIPRO解锁升腾LLM与Stable Diffusion的创意密码

文章目录 引言 一. 香橙派AI PRO配置以及展示优秀的扩展能力实物展示 二、Ascend-LLM模型部署开机xshell连接香橙派实战运行部署运行结果分析开发版表现 三、Stable Diffusion文生图性能表现 四、体验总结性能噪音便捷性 引言 在科技的浪潮中&#xff0c;一场融合智慧与创意的盛…

SpringBoot+Vue的图书销售网站(前后端分离)

技术栈 Java SpringBoot Maven MySQL mybatis Vue Shiro Element-UI 角色对应功能 网站用户 管理员 项目功能截图

C#中的线性表

什么是线性表 线性表是最简单、最基本、最常用的数据结构。线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系。这种一对一的关系指的是数据元素之间的位置关系,即:(1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数…

Kotlin协程最佳实践

使用合适的作用域&#xff1a; 避免使用GlobalScope&#xff0c;因为它的生命周期是整个应用程序&#xff0c;可能会导致内存泄漏。相反&#xff0c;使用与组件生命周期绑定的CoroutineScope&#xff0c;例如在Android中使用lifecycleScope。 管理协程的生命周期&#xff1a; …

代码随想录训练营【贪心算法篇】

贪心 注&#xff1a;本文代码来自于代码随想录 贪心算法一般分为如下四步&#xff1a; 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 这个四步其实过于理论化了&#xff0c;我们平时在做贪心类的题目 很难去按照这四步…

深潜数据海洋:Java文件读写全面解析与实战指南

在软件开发的世界里&#xff0c;文件如同沉默的守护者&#xff0c;承载着程序与现实世界的交流。Java语言&#xff0c;以其强大的文件处理能力&#xff0c;为我们提供了丰富的工具箱&#xff0c;让数据的读写变得既优雅又高效。本文将带你从零开始&#xff0c;逐步深入Java文件…

掌握Python中的文件序列化:Json和Pickle模块解析

Python 文件操作与管理&#xff1a;Open函数、Json与Pickle、Os模块 在Python中&#xff0c;文件是一个重要的数据处理对象。无论是读取数据、保存数据还是进行数据处理&#xff0c;文件操作都是Python编程中不可或缺的一部分。本文将详细介绍Python中文件操作的几种常用方法&…

ImportError: cannot import name ‘packaging‘ from ‘pkg_resources‘

降低setuptools版本 pip install setuptools69.5.1https://github.com/aws-neuron/aws-neuron-sdk/issues/893

阿尔泰科技利用485模块搭建自动灌溉系统实现远程控制

自动灌溉系统又叫土壤墒情监控系统&#xff0c;土壤墒情监控系统主要实现固定站无人值守情况下的土壤墒情数据的自动采集和无线传输&#xff0c;数据在监控中心自动接收入库&#xff1b;可以实现24小时连续在线监控并将监控数据通过有线、无线等传输方式实时传输到监控中心生成…

Express+mysql单表分页条件查询

声明&#xff08;自己还没测试过&#xff0c;只提供大概逻辑&#xff0c;什么多表连接查询可以在原基础上添加&#xff09; class /*** param connection Express的mysql数据库链接对象* current 当前页* pageSize 一页显示行数* where [{key:id,operator:,value15}], key查询…

open3d:ransac分割多个平面(源码)

1、背景介绍 随机采样一致性算法(RANSAC Random Sample Consensus)是一种迭代的参数估计算法,主要用于从包含大量噪声数据的样本中估计模型参数。其核心思想是通过随机采样和模型验证来找到数据中最符合模型假设的点。因此,只要事先给定要提取的参数模型,即可从点云中分割…

[rustlings]13_error_handling

errors6 这一个就是在Err(E)中加了点手脚,就是Err(E)中E的类型也是一个Err类型. 这里是创建了一个新的Err类型,Err类型中有两种不同的枚举值.对于不同的枚举值代表两种不同的错误. // Using catch-all error types like Box<dyn Error> isnt recommended for // library…

【HarmonyOS】HarmonyOS NEXT学习日记:四、布局与容器组件

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;四、布局与容器组件 学习了基础组件之后&#xff0c;想要利用基础组件组装成一个页面&#xff0c;自然就要开始学习布局相关的知识。我理解的ArkUI的布局分为两个部分 一、组件自身的通用属性&#xff0c;诸如weight、height、…

Linux 下的项目开发:从入门到精通

在 Linux 系统上开发项目是一种常见且高效的实践。Linux 提供了强大的工具和环境&#xff0c;使得开发过程更加流畅。本文将带你了解如何在 Linux 下进行项目开发&#xff0c;从环境搭建到代码管理&#xff0c;再到最终的部署。 一、环境搭建 1.1 安装 Linux 发行版 首先&am…

加密软件有什么用?五款电脑文件加密软件推荐

加密软件对于个人和企业来说至关重要&#xff0c;尤其是在2024年这样一个高度数字化的时代&#xff0c;数据安全变得尤为重要。 数据保护&#xff1a;加密软件可以保护敏感信息不被未经授权的人访问。这包括个人数据、财务记录、健康信息、企业机密等。 防泄漏&#xff1a;防…

HarmonyOS工程目录结构

应用级配置文件app.json5 应用唯一标识、版本号、应用图标、应用名称等信息 模块级配置文件module.json5 oh-package.json5 三方库的管理 其他配置 用于编译构建&#xff0c;包括构建配置文件、编译构建任务脚本、混淆规则文件、依赖的共享包信息等。 build-profile.json…