C#控件随窗体变化尺寸修改(未将对象引用设置到对象的实例)

在网上找了一些文章,大多不符合自己的需求。因此贴上自己修改后的代码。

与网上其他代码不同的是,在上述代码中第五行增加了bool类型的变量,主要作用于setTag方法

 因为在实际运行时发现会报错:未将对象引用设置到对象的实例,con.Tag一直为null,判断程序启动后先运行的是FormResize,后运行FormLoad所以才出现了这个问题,所以在formResize方法中加bool用来判断,使运行formLoad后Resize方法才生效,具体代码见下方第5行和27-39行。

复制代码
 1 internal class 窗体控件变化
 2 {
 3     float X;//当前窗体的宽
 4     float Y;//当前窗体的高
 5     bool openResize = false;//Resize方法启动
 6     public void formLoad(Form form)
 7     {
 8         //将当前窗体的宽和高赋值给XY
 9         X = form.Width;
10         Y = form.Height;
11         //保存控件的各个属性
12         setTag(form);
13         openResize = true;
14     }
15     public void formResize(Form form)
16     {
17         if (openResize == true)
18         {
19             //获取当前宽高度与初始宽高度的比例
20             float newX = form.Width / X;
21             float newY = form.Height / Y;
22             setControls(newX, newY, form);
23         }
24         
25     }
26     //保存控件属性值
27     public void setTag(Control cons)
28     {
29         //遍历窗体内的控件,将各属性存入Tag
30         foreach (Control con in cons.Controls)
31         {
32             /*
33              在VS2015上运行正常,在VS2017、19运行会报错:未将对象引用设置到对象的实例,con.Tag一直为null
34             判断启动后先运行的是Resize,后运行Load所以才出现了这个问题,所以在formResize方法中加bool用来判断,使运行formLoad后Resize方法才生效
35              */
36             con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
37             if(con.Controls.Count > 0) setTag(con);
38         }
39     }
40     //跟随屏幕调整控件大小
41     public void setControls(float newX, float newY, Control cons)
42     {
43         //遍历控件,重设值
44             foreach (Control con in cons.Controls)
45             {
46                 //获取控件的Tag,分割的属性存入数组
47                 string[] myTag = con.Tag.ToString().Split(new char[] { ':' });
48                 //根据窗体缩放比例确定控件的值
49                 float a = Convert.ToSingle(myTag[0]) * newX;
50                 con.Width = (int)a;
51                 a = Convert.ToSingle(myTag[1]) * newY;
52                 con.Height = (int)a;
53                 a = Convert.ToSingle(myTag[2]) * newX;
54                 con.Left = (int)a;
55                 a = Convert.ToSingle(myTag[3]) * newY;
56                 con.Top = (int)a;
57                 Single currentSize = Convert.ToSingle(myTag[4]) * (newX);//字体大小
58                 con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
59                 if (con.Controls.Count > 0)
60                 {
61                     setControls(newX, newY, cons);
62                 }
63             }
64     }
65 }
复制代码

自己修改后,作为一个类来使用,因此有多个页面需要实现控件变化时,只需要创建对象并调用formLoad和formResize方法就行,使用方法:

1.新建一个类,内容就是上面代码

2.在窗体页面中创建对象,在窗体加载事件中调用formLoad方法,在窗体Resize事件中调用formResize方法

复制代码
 1 namespace 命名空间
 2 {
 3     public partial class 主页面 : Form
 4     {
 5         窗体控件变化 flowSize = new 窗体控件变化();
 6         public 主页面()
 7         {
 8             InitializeComponent();
 9         }
10         private void 主页面_Load(object sender, EventArgs e)
11         {
12             //控件大小跟随窗体尺寸变化
13             flowSize.formLoad(this);
14         }
15         private void 主页面_Resize(object sender, EventArgs e)
16         {
17            //控件大小跟随窗体尺寸变化
18            flowSize.formResize(this);
19         }
20         
21     }
22 }    
复制代码

随便在窗体中添加几个控件,运行即可查看效果(panel、groupbox等控件除外),panel、groupbox等部分控件会导致程序出错,因为暂时还没用到,暂不解决,后续再补上解决方案


posted @   用户_我的好友  阅读(174)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示