这个功能网上很多人在问,也有不少人给出过答案,经过实际使用,觉得网上这段代码实现的效果比较好,记录一下

核心代码就是下面这个类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Forms;
  6.  
  7. namespace UAVRadar
  8. {
  9. public class AutoSizeFormClass
  10. {
  11. //(1).声明结构,只记录窗体和其控件的初始位置和大小。
  12. public struct controlRect
  13. {
  14. public int Left;
  15. public int Top;
  16. public int Width;
  17. public int Height;
  18. }
  19. //(2).声明 1个对象
  20. //注意这里不能使用控件列表记录 List nCtrl;,因为控件的关联性,记录的始终是当前的大小。
  21. // public List oldCtrl= new List();//这里将西文的大于小于号都过滤掉了,只能改为中文的,使用中要改回西文
  22. public List<controlRect> oldCtrl = new List<controlRect>();
  23. int ctrlNo = ;//1;
  24. //(3). 创建两个函数
  25. //(3.1)记录窗体和其控件的初始位置和大小,
  26. public void controllInitializeSize(Control mForm)
  27. {
  28. controlRect cR;
  29. cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
  30. oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可
  31. AddControl(mForm);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
  32. //this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化
  33. //0 - Normalize , 1 - Minimize,2- Maximize
  34. }
  35. private void AddControl(Control ctl)
  36. {
  37. foreach (Control c in ctl.Controls)
  38. { //**放在这里,是先记录控件的子控件,后记录控件本身
  39. //if (c.Controls.Count > 0)
  40. // AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
  41. controlRect objCtrl;
  42. objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;
  43. oldCtrl.Add(objCtrl);
  44. //**放在这里,是先记录控件本身,后记录控件的子控件
  45. if (c.Controls.Count > )
  46. AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
  47. }
  48. }
  49. //(3.2)控件自适应大小,
  50. public void controlAutoSize(Control mForm)
  51. {
  52. if (ctrlNo == )
  53. { //*如果在窗体的Form1_Load中,记录控件原始的大小和位置,正常没有问题,但要加入皮肤就会出现问题,因为有些控件如dataGridView的的子控件还没有完成,个数少
  54. //*要在窗体的Form1_SizeChanged中,第一次改变大小时,记录控件原始的大小和位置,这里所有控件的子控件都已经形成
  55. controlRect cR;
  56. // cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
  57. cR.Left = ; cR.Top = ; cR.Width = mForm.PreferredSize.Width; cR.Height = mForm.PreferredSize.Height;
  58.  
  59. oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可
  60. AddControl(mForm);//窗体内其余控件可能嵌套其它控件(比如panel),故单独抽出以便递归调用
  61. }
  62. float wScale = (float)mForm.Width / (float)oldCtrl[].Width;//新旧窗体之间的比例,与最早的旧窗体
  63. float hScale = (float)mForm.Height / (float)oldCtrl[].Height;//.Height;
  64. ctrlNo = ;//进入=1,第0个为窗体本身,窗体内的控件,从序号1开始
  65. AutoScaleControl(mForm, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
  66. }
  67. private void AutoScaleControl(Control ctl, float wScale, float hScale)
  68. {
  69. int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;
  70. //int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始
  71. foreach (Control c in ctl.Controls)
  72. { //**放在这里,是先缩放控件的子控件,后缩放控件本身
  73. //if (c.Controls.Count > 0)
  74. // AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
  75. ctrLeft0 = oldCtrl[ctrlNo].Left;
  76. ctrTop0 = oldCtrl[ctrlNo].Top;
  77. ctrWidth0 = oldCtrl[ctrlNo].Width;
  78. ctrHeight0 = oldCtrl[ctrlNo].Height;
  79. //c.Left = (int)((ctrLeft0 - wLeft0) * wScale) + wLeft1;//新旧控件之间的线性比例
  80. //c.Top = (int)((ctrTop0 - wTop0) * h) + wTop1;
  81. c.Left = (int)((ctrLeft0) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加 + wLeft1
  82. c.Top = (int)((ctrTop0) * hScale);//
  83. c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 (int)(c.Width * w);
  84. c.Height = (int)(ctrHeight0 * hScale);//
  85. ctrlNo++;//累加序号
  86. //**放在这里,是先缩放控件本身,后缩放控件的子控件
  87. if (c.Controls.Count > )
  88. AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
  89.  
  90. if (ctl is DataGridView)
  91. {
  92. DataGridView dgv = ctl as DataGridView;
  93. Cursor.Current = Cursors.WaitCursor;
  94.  
  95. int widths = ;
  96. for (int i = ; i < dgv.Columns.Count; i++)
  97. {
  98. dgv.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells); // 自动调整列宽
  99. widths += dgv.Columns[i].Width; // 计算调整列后单元列的宽度和
  100. }
  101. if (widths >= ctl.Size.Width) // 如果调整列的宽度大于设定列宽
  102. dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells; // 调整列的模式 自动
  103. else
  104. dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; // 如果小于 则填充
  105.  
  106. Cursor.Current = Cursors.Default;
  107. }
  108. }
  109.  
  110. }
  111. }
  112. }

界面调用的代码如下:

  1. private AutoSizeFormClass asc = new AutoSizeFormClass();
  2. public MainWindow()
  3. {
  4. InitializeComponent();
  5. asc.controllInitializeSize(this);
  6. }
  7.  
  8. private void MainWindow_Resize(object sender, EventArgs e)
  9. {
  10. //int length = this.Width;
  11. //int high = this.Height;
  12. asc.controlAutoSize(this);
  13. }

winform 控件随页面大小进行自适应的更多相关文章

  1. C# Winform控件字体大小自适应

    using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace WGClie ...

  2. WPF保存包含Winform控件的XAML页面问题

    原文:WPF保存包含Winform控件的XAML页面问题 最近的工作中,用到了WPF调用Winform控件 但是在保存XAML页面的时候发现了问题,就是Winform页面黑黑的,没有任何渲染的波形曲线 ...

  3. C# ——窗体和控件随着分辨率的变化自适应大小

    一.说明 我们自己编写程序的界面,会遇到各种屏幕分辨 率,只有自适应才能显的美观.实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比 ...

  4. C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器

    在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...

  5. Winform控件Tag使用规范

    背景 Tag在WinForm控件中经常被用来存储临时数据,类型为object,但是当程序中多个地方使用到Tag时,容易造成Tag使用的混乱,Tag是如此重要的一个属性,应该要好好考虑下如何有效的使用T ...

  6. 浅谈Winform控件开发(一):使用GDI+美化基础窗口

    写在前面: 本系列随笔将作为我对于winform控件开发的心得总结,方便对一些读者在GDI+.winform等技术方面进行一个入门级的讲解,抛砖引玉. 别问为什么不用WPF,为什么不用QT.问就是懒, ...

  7. 在WPF中使用WinForm控件方法

    1.      首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2.      在要使用WinForm控 ...

  8. WPF 调用WinForm控件

    WPF可以使用WindowsFormsHost控件做为容器去显示WinForm控件,类似的用法网上到处都是,就是拖一个WindowsFormsHost控件winHost1到WPF页面上,让后设置win ...

  9. WinForm控件TreeView 只部分节点显示 CheckBox

    WinForm控件TreeView 只部分节点显示  CheckBox 用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示check ...

随机推荐

  1. ubuntu 14.04安装c++遇到的问题

    这是我在安装c++编译器时遇到的一些问题和解决办法,总结一下希望以后的人能少走弯路 安装g++编译器:sudo apt-get install build-essential build-essent ...

  2. CF910B

    题解: dp f[i][j]表示i根a,j根b要多少 然后随便转移一下 代码: #include<bits/stdc++.h> using namespace std; ][],n,a,b ...

  3. hystrix -hystrixCommand配置介绍

    public @interface HystrixCommand { // HystrixCommand 命令所属的组的名称:默认注解方法类的名称 String groupKey() default ...

  4. Week09《java程序设计》第九次作业总结

    Week09<java程序设计>第九次作业总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 答: 2. 书面作业 本次作业题集集合 1. Li ...

  5. 一道简单的JavaScript面试题

    好久没更新博客了,随便写点东西吧. 自从工作之后就特别忙,忙的过程中有时候挺迷茫的,可能是大多数时候写的都是简单的业务代码,很久没好好充电了.最近一直在零碎的上班路上等电梯时间里面学习<图解HT ...

  6. cpu的用户态和内核态和内存的用户空间内核空间

    谈到CPU的这两个工作状态,也就是处理器的这两个工作状态,那我们有必要说一下为什么搞出这两个鬼玩意出来.       用过电脑的娃娃们肯定知道在一个系统中既有操作系统的程序,也由普通用户的程序.但那么 ...

  7. 有关项目依赖包发生 Manifest Merge 冲突的详细解决方案

    安卓开发使用 Gradle 插件管理依赖包确实非常方便,尤其是在解决一些依赖冲突的问题上.比如,重复依赖的问题,具体内容请我之前写的一篇文章: 有关 Android Studio 重复引入包的问题和解 ...

  8. java.lang.IllegalArgumentException: Invalid character found in method name

    1.错误描述 信息: Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors ...

  9. python全局替换文件内容脚本第1版

    #!/usr/bin/python #coding=utf8 """ # Author: xiaoyafei # Created Time : 2018-05-08 09 ...

  10. python sys.path.append()和sys.path.insert()

    python程序中使用 import XXX 时,python解析器会在当前目录.已安装和第三方模块中搜索 xxx,如果都搜索不到就会报错. 使用sys.path.append()方法可以临时添加搜索 ...