探查窗体---进阶编程篇(三)

  在C#窗体应用程序开发中,窗体也是类,按照正常的先后顺序来说,应该先介绍下接口和类再应该介绍窗体的,但是此处我会根据最常用和很容易忽略的地方来讲解编程开发,更多的是提供一些自我思考的思路。

  我们一开始学习的时候,都是从控制台程序学习,后来就想要做界面,自然而然的就接触到了winform程序,然后使用了非常简单,操作流程的方式将控件拖到了窗体中,然后点击控件,开始修改一些属性参数,稍微多使用几次后,就会非常的娴熟,我刚开始接触时也不会去深究背后的原理技术是什么。上述的一系列操作关联了非常多的技术细节,有许多的细节都是比较高级的主题,在初学者中确实不应该提及,但此处为了讲明白这些原理却又不得不提专业名词,我相信只要是我们真的想学习编程,就一定想知道它为什么就能实现这些功能。

  我们还是一个最简单的winform窗体程序作为切入点,新建一个窗体程序后:

  我们抛开设计器不谈(设计器中其实没有代码支持,只是IDE提供的一个可视化操作效果),一个窗体程序,就是一个类,只不过在两个地方定义了,第一部分是我们在代码开发中经常碰到的,几乎所有的代码都在这里开发完成。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Threading.Tasks;
 9 using System.Windows.Forms;
10 
11 namespace WindowsFormsApp1
12 {
13     public partial class Form1 : Form
14     {
15         public Form1()
16         {
17             InitializeComponent();
18         }
19         
20     }
21 }

第二部分的代码藏的比较深,在Form1.Designer.cs中,至于资源存储不再本次的讨论范围内。

 

 1 namespace WindowsFormsApp1
 2 {
 3     partial class Form1
 4     {
 5         /// <summary>
 6         /// 必需的设计器变量。
 7         /// </summary>
 8         private System.ComponentModel.IContainer components = null;
 9 
10         /// <summary>
11         /// 清理所有正在使用的资源。
12         /// </summary>
13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14         protected override void Dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.Dispose();
19             }
20             base.Dispose(disposing);
21         }
22 
23         #region Windows 窗体设计器生成的代码
24 
25         /// <summary>
26         /// 设计器支持所需的方法 - 不要修改
27         /// 使用代码编辑器修改此方法的内容。
28         /// </summary>
29         private void InitializeComponent()
30         {
31             this.SuspendLayout();
32             // 
33             // Form1
34             // 
35             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
36             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
37             this.ClientSize = new System.Drawing.Size(528, 375);
38             this.Name = "Form1";
39             this.Text = "Form1";
40             this.ResumeLayout(false);
41 
42         }
43 
44         #endregion
45     }
46 }

 

  我们可以清楚的看到第一部分的构造方法中调用了InitializeComponent()方法,该方法的源代码就在第二个文件中,我们来看看源代码中都写了什么,挂起布局,设置放大缩小维度,模式,窗口大小,窗体名称,显示文本,恢复布局。OK,看到这里,我相信各位看官都可以尝试着修改修改参数,看看会不会有什么变化,比如修改下窗体名称,大小等等。再回到设计器界面就可以看到已经修改完成了,接下来就是重头戏了,我们尝试着在窗体上添加一个按钮,就是拖控件的方式,拖上去后看看代码会不会变化:

  就是这样的效果,先不要去追加按钮事件,或是调整按钮大小,我们来看看form1类的代码会不会发生变化,我们发现Form1.cs中的代码没有任何改变,那么我们可以肯定另一个文件中发生了代码变化:

 1 namespace WindowsFormsApp1
 2 {
 3     partial class Form1
 4     {
 5         /// <summary>
 6         /// 必需的设计器变量。
 7         /// </summary>
 8         private System.ComponentModel.IContainer components = null;
 9 
10         /// <summary>
11         /// 清理所有正在使用的资源。
12         /// </summary>
13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14         protected override void Dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.Dispose();
19             }
20             base.Dispose(disposing);
21         }
22 
23         #region Windows 窗体设计器生成的代码
24 
25         /// <summary>
26         /// 设计器支持所需的方法 - 不要修改
27         /// 使用代码编辑器修改此方法的内容。
28         /// </summary>
29         private void InitializeComponent()
30         {
31             this.button1 = new System.Windows.Forms.Button();
32             this.SuspendLayout();
33             // 
34             // button1
35             // 
36             this.button1.Location = new System.Drawing.Point(238, 42);
37             this.button1.Name = "button1";
38             this.button1.Size = new System.Drawing.Size(75, 23);
39             this.button1.TabIndex = 0;
40             this.button1.Text = "button1";
41             this.button1.UseVisualStyleBackColor = true;
42             // 
43             // Form1
44             // 
45             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
46             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
47             this.ClientSize = new System.Drawing.Size(528, 375);
48             this.Controls.Add(this.button1);
49             this.Name = "Form1";
50             this.Text = "FormMy";
51             this.ResumeLayout(false);
52 
53         }
54 
55         #endregion
56 
57         private System.Windows.Forms.Button button1;
58     }
59 }

  我们看到除了button1的声明在form1类的下面,按钮的实例化和属性设置全部都是在方法InitializeComponent()中完成的,我们也可以尝试着改改this.button1.Text = "测试按钮";再回到界面设计器,发现同步更改了,如果我们在form1.cs中的任何的方法中更改button1的text,发现并没有更改,所以我们可以得出一个结论,InitializeComponent()方法在设计器支持中非常的关键,中间的所有代码将会影响设计器中的布局显示。

  说完上述的内容后,您可以按F11键,进行分步调试,直到应用程序退出为止,这样就对整个程序执行的过程非常清晰,一个类被实例化以后,里面的变量一定是最先执行的。

  1. Program.cs文件中的Main方法最先执行
  2. 实例化窗口,配置窗口字段
  3. 执行构造方法,加载所有的控件资源
  4. 显示
  5. 关闭前执行dispose方法
  6. 退出Main方法。

  值得注意的是,窗体有四个常用的事件,关联事件后如下:

 1         private void Form1_Load(object sender, EventArgs e)
 2         {
 3             MessageBox.Show("Load");
 4         }
 5 
 6         private void Form1_Shown(object sender, EventArgs e)
 7         {
 8             MessageBox.Show("Show");
 9         }
10 
11         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
12         {
13             MessageBox.Show("Closing");
14         }
15 
16         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
17         {
18             MessageBox.Show("Closed");
19         }

  可以将一些初始化的代码放入到Load方法和Show方法中,区别就在于Load是在窗体显示前执行的,这时候窗体已经实例化了,并且加载了控件,而show就是在窗体已经可以显示时候执行的。如果在show方法中执行一些比较耗时的代码的话,就会明显的感觉窗体显示出来的时候卡顿了一会,这种情况就放到load方法中比较合适。如果有退出窗体的确认或是密码验证的需求,可以在formClosing中编写。下面举个例子说明退出确认:

1         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
2         {
3             if (MessageBox.Show("是否真的退出窗口?", "退出确认", MessageBoxButtons.YesNo) == DialogResult.No)
4             {
5                 e.Cancel = true;
6             }
7             //MessageBox.Show("Closing");
8         }

 

动态控件

  有时候我们希望创建一个动态的按钮出来,就是原先它不存在的,突然有了,还可以点击(按照道理上我们可以使用一个按钮的Visible属性来控制显示和消失可以达到相似的目的),但是我们仍然需要知道控件是怎么创造出来的,比如上述项目按钮点击一下在旁边生成一个新的按钮,具体怎么生成,我们可以参照button1是怎么生成的,所以如下代码:

 1         private void button1_Click(object sender, EventArgs e)
 2         {
 3             Button button = new Button();
 4             button.Location = new System.Drawing.Point(328, 42);
 5             button.Name = "button2";
 6             button.Size = new System.Drawing.Size(75, 23);
 7             button.TabIndex = 0;
 8             button.Text = "button2";
 9             button.UseVisualStyleBackColor = true;
10 
11             this.Controls.Add(button);
12         }

点击之后的效果如下:

  如果我们希望按钮2可以支持点击事件,则稍微修改下代码即可:

 1         private void button1_Click(object sender, EventArgs e)
 2         {
 3             Button button = new Button();
 4             button.Location = new System.Drawing.Point(328, 42);
 5             button.Name = "button2";
 6             button.Size = new System.Drawing.Size(75, 23);
 7             button.TabIndex = 0;
 8             button.Text = "button2";
 9             button.UseVisualStyleBackColor = true;
10             button.Click += Button_Click;
11 
12             this.Controls.Add(button);
13         }
14 
15         private void Button_Click(object sender, EventArgs e)
16         {
17             MessageBox.Show("你点击了button2");
18         }

属性说明

  我们很习惯于选择控件后设置属性,就像下面这张图片一样:

  设置光标也好,文本也罢,不知道细心的你有没有发现,我们为什么能这样设置,这个IDE的属性设计器为什么能知道控件的属性以及需要设置的数据内容,这一切的一切都被深深的藏在了底层,VS首先加载动态链接库,找到控件内容,然后通过反射来获取到属性名称,属性类别,等你在上面窗口设置好新的值后,就生成相应的代码来覆盖原有的值。至于所有属性的解释,都是特性来完成的,以后在讲解自定义控件的时候,再来着重说明。

 

转载于:https://www.cnblogs.com/dathlin/p/7239121.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值