C# WinForm form and its controls adapt to various screen resolutions

C# WinForm form and its controls adapt to various screen resolutions

July 13, 2016 17:12:31 source0573 read 9327

1. Declare the AutoSizeFormClass class

 

 
  1. using System;

  2. using System.Collections.Generic;

  3. using System.Linq;

  4. using System.Text;

  5. using System.Windows.Forms;

  6.  
  7. namespace WindowsApplication1

  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 = 0;//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 > 0)

  46. AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用

  47. }

  48. }

  49. //(3.2)控件自适应大小,

  50. public void controlAutoSize(Control mForm)

  51. {

  52. if (ctrlNo == 0)

  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 = 0; cR.Top = 0; 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[0].Width;//新旧窗体之间的比例,与最早的旧窗体

  63. float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height;

  64. ctrlNo = 1;//进入=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 > 0)

  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 = 0;

  96. for (int i = 0; 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. }

  113. }


2. Add a Load event to the form, and in its method Form1_Load, call the initialization method of the class to record the initial position and size of the form and its controls

3. Add the SizeChanged event to the form, and in its method Form1_SizeChanged, call the adaptive method of the class to complete the adaptive

 

 
  1. using System;

  2. using System.Collections.Generic;

  3. using System.ComponentModel;

  4. using System.Data;

  5. using System.Drawing;

  6. using System.Text;

  7. using System.Windows.Forms;

  8.  
  9. namespace WindowsApplication1

  10. {

  11. public partial class Form1 : Form

  12. {

  13. //1.声明自适应类实例

  14. AutoSizeFormClass asc = new AutoSizeFormClass();

  15.  
  16. public Form1()

  17. {

  18. InitializeComponent();

  19. }

  20.  
  21. //2. 为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件的初始位置和大小

  22. private void Form1_Load(object sender, EventArgs e)

  23. {

  24. asc.controllInitializeSize(this);

  25. }

  26.  
  27. //3.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应

  28. private void Form1_SizeChanged(object sender, EventArgs e)

  29. {

  30. asc.controlAutoSize(this);

  31. }

  32. }

  33. }

Guess you like

Origin blog.csdn.net/hewusheng10/article/details/98844104