winform 控件随页面大小进行自适应
这个功能网上很多人在问,也有不少人给出过答案,经过实际使用,觉得网上这段代码实现的效果比较好,记录一下
核心代码就是下面这个类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- namespace UAVRadar
- {
- public class AutoSizeFormClass
- {
- //(1).声明结构,只记录窗体和其控件的初始位置和大小。
- public struct controlRect
- {
- public int Left;
- public int Top;
- public int Width;
- public int Height;
- }
- //(2).声明 1个对象
- //注意这里不能使用控件列表记录 List nCtrl;,因为控件的关联性,记录的始终是当前的大小。
- // public List oldCtrl= new List();//这里将西文的大于小于号都过滤掉了,只能改为中文的,使用中要改回西文
- public List<controlRect> oldCtrl = new List<controlRect>();
- int ctrlNo = ;//1;
- //(3). 创建两个函数
- //(3.1)记录窗体和其控件的初始位置和大小,
- public void controllInitializeSize(Control mForm)
- {
- controlRect cR;
- cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
- oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可
- AddControl(mForm);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
- //this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化
- //0 - Normalize , 1 - Minimize,2- Maximize
- }
- private void AddControl(Control ctl)
- {
- foreach (Control c in ctl.Controls)
- { //**放在这里,是先记录控件的子控件,后记录控件本身
- //if (c.Controls.Count > 0)
- // AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
- controlRect objCtrl;
- objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;
- oldCtrl.Add(objCtrl);
- //**放在这里,是先记录控件本身,后记录控件的子控件
- if (c.Controls.Count > )
- AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
- }
- }
- //(3.2)控件自适应大小,
- public void controlAutoSize(Control mForm)
- {
- if (ctrlNo == )
- { //*如果在窗体的Form1_Load中,记录控件原始的大小和位置,正常没有问题,但要加入皮肤就会出现问题,因为有些控件如dataGridView的的子控件还没有完成,个数少
- //*要在窗体的Form1_SizeChanged中,第一次改变大小时,记录控件原始的大小和位置,这里所有控件的子控件都已经形成
- controlRect cR;
- // cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
- cR.Left = ; cR.Top = ; cR.Width = mForm.PreferredSize.Width; cR.Height = mForm.PreferredSize.Height;
- oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可
- AddControl(mForm);//窗体内其余控件可能嵌套其它控件(比如panel),故单独抽出以便递归调用
- }
- float wScale = (float)mForm.Width / (float)oldCtrl[].Width;//新旧窗体之间的比例,与最早的旧窗体
- float hScale = (float)mForm.Height / (float)oldCtrl[].Height;//.Height;
- ctrlNo = ;//进入=1,第0个为窗体本身,窗体内的控件,从序号1开始
- AutoScaleControl(mForm, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
- }
- private void AutoScaleControl(Control ctl, float wScale, float hScale)
- {
- int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;
- //int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始
- foreach (Control c in ctl.Controls)
- { //**放在这里,是先缩放控件的子控件,后缩放控件本身
- //if (c.Controls.Count > 0)
- // AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
- ctrLeft0 = oldCtrl[ctrlNo].Left;
- ctrTop0 = oldCtrl[ctrlNo].Top;
- ctrWidth0 = oldCtrl[ctrlNo].Width;
- ctrHeight0 = oldCtrl[ctrlNo].Height;
- //c.Left = (int)((ctrLeft0 - wLeft0) * wScale) + wLeft1;//新旧控件之间的线性比例
- //c.Top = (int)((ctrTop0 - wTop0) * h) + wTop1;
- c.Left = (int)((ctrLeft0) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加 + wLeft1
- c.Top = (int)((ctrTop0) * hScale);//
- c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 (int)(c.Width * w);
- c.Height = (int)(ctrHeight0 * hScale);//
- ctrlNo++;//累加序号
- //**放在这里,是先缩放控件本身,后缩放控件的子控件
- if (c.Controls.Count > )
- AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
- if (ctl is DataGridView)
- {
- DataGridView dgv = ctl as DataGridView;
- Cursor.Current = Cursors.WaitCursor;
- int widths = ;
- for (int i = ; i < dgv.Columns.Count; i++)
- {
- dgv.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells); // 自动调整列宽
- widths += dgv.Columns[i].Width; // 计算调整列后单元列的宽度和
- }
- if (widths >= ctl.Size.Width) // 如果调整列的宽度大于设定列宽
- dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells; // 调整列的模式 自动
- else
- dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; // 如果小于 则填充
- Cursor.Current = Cursors.Default;
- }
- }
- }
- }
- }
界面调用的代码如下:
- private AutoSizeFormClass asc = new AutoSizeFormClass();
- public MainWindow()
- {
- InitializeComponent();
- asc.controllInitializeSize(this);
- }
- private void MainWindow_Resize(object sender, EventArgs e)
- {
- //int length = this.Width;
- //int high = this.Height;
- asc.controlAutoSize(this);
- }
winform 控件随页面大小进行自适应的更多相关文章
- C# Winform控件字体大小自适应
using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace WGClie ...
- WPF保存包含Winform控件的XAML页面问题
原文:WPF保存包含Winform控件的XAML页面问题 最近的工作中,用到了WPF调用Winform控件 但是在保存XAML页面的时候发现了问题,就是Winform页面黑黑的,没有任何渲染的波形曲线 ...
- C# ——窗体和控件随着分辨率的变化自适应大小
一.说明 我们自己编写程序的界面,会遇到各种屏幕分辨 率,只有自适应才能显的美观.实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比 ...
- C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器
在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...
- Winform控件Tag使用规范
背景 Tag在WinForm控件中经常被用来存储临时数据,类型为object,但是当程序中多个地方使用到Tag时,容易造成Tag使用的混乱,Tag是如此重要的一个属性,应该要好好考虑下如何有效的使用T ...
- 浅谈Winform控件开发(一):使用GDI+美化基础窗口
写在前面: 本系列随笔将作为我对于winform控件开发的心得总结,方便对一些读者在GDI+.winform等技术方面进行一个入门级的讲解,抛砖引玉. 别问为什么不用WPF,为什么不用QT.问就是懒, ...
- 在WPF中使用WinForm控件方法
1. 首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2. 在要使用WinForm控 ...
- WPF 调用WinForm控件
WPF可以使用WindowsFormsHost控件做为容器去显示WinForm控件,类似的用法网上到处都是,就是拖一个WindowsFormsHost控件winHost1到WPF页面上,让后设置win ...
- WinForm控件TreeView 只部分节点显示 CheckBox
WinForm控件TreeView 只部分节点显示 CheckBox 用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示check ...
随机推荐
- ubuntu 14.04安装c++遇到的问题
这是我在安装c++编译器时遇到的一些问题和解决办法,总结一下希望以后的人能少走弯路 安装g++编译器:sudo apt-get install build-essential build-essent ...
- CF910B
题解: dp f[i][j]表示i根a,j根b要多少 然后随便转移一下 代码: #include<bits/stdc++.h> using namespace std; ][],n,a,b ...
- hystrix -hystrixCommand配置介绍
public @interface HystrixCommand { // HystrixCommand 命令所属的组的名称:默认注解方法类的名称 String groupKey() default ...
- Week09《java程序设计》第九次作业总结
Week09<java程序设计>第九次作业总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 答: 2. 书面作业 本次作业题集集合 1. Li ...
- 一道简单的JavaScript面试题
好久没更新博客了,随便写点东西吧. 自从工作之后就特别忙,忙的过程中有时候挺迷茫的,可能是大多数时候写的都是简单的业务代码,很久没好好充电了.最近一直在零碎的上班路上等电梯时间里面学习<图解HT ...
- cpu的用户态和内核态和内存的用户空间内核空间
谈到CPU的这两个工作状态,也就是处理器的这两个工作状态,那我们有必要说一下为什么搞出这两个鬼玩意出来. 用过电脑的娃娃们肯定知道在一个系统中既有操作系统的程序,也由普通用户的程序.但那么 ...
- 有关项目依赖包发生 Manifest Merge 冲突的详细解决方案
安卓开发使用 Gradle 插件管理依赖包确实非常方便,尤其是在解决一些依赖冲突的问题上.比如,重复依赖的问题,具体内容请我之前写的一篇文章: 有关 Android Studio 重复引入包的问题和解 ...
- java.lang.IllegalArgumentException: Invalid character found in method name
1.错误描述 信息: Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors ...
- python全局替换文件内容脚本第1版
#!/usr/bin/python #coding=utf8 """ # Author: xiaoyafei # Created Time : 2018-05-08 09 ...
- python sys.path.append()和sys.path.insert()
python程序中使用 import XXX 时,python解析器会在当前目录.已安装和第三方模块中搜索 xxx,如果都搜索不到就会报错. 使用sys.path.append()方法可以临时添加搜索 ...