zoukankan      html  css  js  c++  java
  • 探查窗体---进阶编程篇(三)

      在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首先加载动态链接库,找到控件内容,然后通过反射来获取到属性名称,属性类别,等你在上面窗口设置好新的值后,就生成相应的代码来覆盖原有的值。至于所有属性的解释,都是特性来完成的,以后在讲解自定义控件的时候,再来着重说明。

  • 相关阅读:
    windows开启PostgreSQL数据库远程访问
    Git使用介绍
    linux 常用工具记录及简介
    ubuntu18 安装坑点记录(华硕飞行堡垒)
    快手自动视频随机点赞脚本
    接触手机脚本编程------基于触动精灵的lua编程
    使电脑蜂鸣器发声小脚本
    tensorflow--非线性回归
    python笔记--------numpy
    python笔记--------二
  • 原文地址:https://www.cnblogs.com/dathlin/p/7239121.html
Copyright © 2011-2022 走看看