第一章:初识Windows程序

本章目标

  1. 掌握Windows程序的开发步骤
  2. 会使用基本控件设计窗体
  3. 会编写简单的事件处理程序

本章内容

创建Windows程序

  1. 创建新项目,选择Windows程序

    1713866946398

    1713867033338

  2. 资源管理理介绍

    1713867203624

  3. 程序入口,Main方法介绍

    1. 位于 Program.cs 文件

    2. Main()方法是Windows程序的入口,可以通过此方法,启动不同窗体

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]
      static void Main()
      {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new Form1());//如果要启动其他窗体,修改此行代码
      }
  4. Windows窗体编辑视图

    1. 窗体设计器

      1714123164831

    2. 代码编辑器

      1714123241912

  5. partial让程序更清晰

    partial是部分的意思,同一个类型的各个部分都必须有,修饰符在编译的时候仍会将各个部分的局部类型合并成一个完整的类。

    用 partial 将同一个窗体的代码分开放在两个文件中:

    • 一个存放 VS 自动生成的代码
    • 一个存放我们自己编写的代码

    注意事项:

    最终这二个文件会生成一个类

    1714123482385

窗体常用属性

  1. 窗体属性二种顺序排列方式:分类或字母

    1714376911551

  2. 窗体常用属性,按分类模式讲解

    1. 布局属性

      1. StartPosition 属性:用来获取或设置程序运行时窗体的初始显示位置,该属性有5个可选属性值,默认值 WindowsDefaultLocation。属性值如下表:

        属性值 说明
        Manual(手动) 窗体的初始显示位置由Location属性决定
        CenterScreen(屏幕中央) 窗体定位在当前显示屏幕窗口中居中,其尺寸在窗体大小Size中指定
        WindowsDefaultLocation(默认位置,偏左上) 窗体定位在windows默认位置,其尺寸在窗体大小Size中指定
        WindowsDefaultBounds(默认位置和边界) 窗体定位在windows默认位置,其边界也由windows默认指定
        CenterParent(父窗体中央) 窗体在其父窗体中居中位置
      2. 尺寸属性:

        • AutoSize:bool型,指示控件尺寸是否与其内容自适应,初始为false。
        • MaximumSize:Size型,定义窗体可以调整到的最大尺寸,初始为(0,0)。(注:初始时,相当于不起作用,可以随意拉大)
        • MinimumSize:Size型,定义窗体可以调整到的最小尺寸,初始为(0,0)。
        • Size:Size型,定义控件的尺寸(宽,高)。
      3. WindowState属性:

        FormWindowState枚举型,定义窗体显示的初始状态,初始为Normal。

        属性值 说明
        Normal 常态显示
        Minimizied 最小化显示
        Maximized 最大化显示
    2. 窗口样式:

      (1)ControlBox属性:bool型,指示窗体标题栏是否有系统菜单按钮(最小化、最大化、叉)和图标,初始为true。

      (2)HelpButton属性:bool型,指示窗体标题栏是否有帮助按钮,初始为false。(注:只有当没有最小化按钮和最大化按钮时,这个属性设置为true才有效,帮助按钮显示在叉的旁边)

      (3)Icon属性:Icon型,定义窗体标题栏和任务栏的图标,初始为系统图标,可通过导入.ico图标文件修改图标。

      (4)MaximizeBox属性:bool型,指示窗体标题栏是否有最大化按钮。

      (5)MinimizeBox属性:bool型,指示窗体标题栏是否有最小化按钮。

      (6)Opacity属性:double型,定义窗体的不透明度百分比,初始为100%,即完全不透明。

      (7)ShowIcon属性:bool型,指示窗体图标是否显示在标题栏上,初始为ture。

      (8)ShowInTaskbar属性:bool型,指示窗体是否出现在任务栏中,初始为ture。

      (9)SizeGripSize属性:SizeGripSize枚举型,定义窗体右下角显示调整大小手柄的模式,枚举值有Auto(自动)、Hide(隐藏)、Show(显示),初始为Auto。

      (10)TopMost属性:bool型,指示窗体是否始终显示在所有窗体之上,初始为false。

      (11)TransparencyKey属性:Color型,定义绘制到窗体上显示透明的颜色,初始为空。

      (12)IsMdiContainer属性:用来获取或设置一个值,该值指示窗体是否为多文档界面中的子窗体的容器。值为True时,窗体是子窗体的容器,为False时,不是子窗体的容器,默认值为False。

      (13)MainMenuStrip属性:设置窗体的主菜单,在窗体中添加MenuStrip控件时,Visual Studio .NET会自动完成该属性设置。

    3. 设计样式

      (1)Name:string型,定义窗体的成员变量名,初始为“Form1”。

      (2)Locked:bool型,指示在设计时是否锁定窗体的尺寸,初始为false。(注:将此项设置为true将导致无法拖动设置窗体尺寸,但仍可以通过写代码修改窗体的尺寸)

    4. 外观属性

      (1)Text:string型,定义窗体标题文本,初始为“Form1”。

      (2)BackColor:Color型,定义窗体的背景色,初始为系统颜色Control。

      (3)BackgroundImage:Image型,定义窗体的背景图,初始为空。

      (4)BackgroundImageLayout:ImageLayout枚举型,定义窗体的背景图像布局方式,枚举值有None(靠左显示)、Tile(重复显示)、Center(居中显示)、Stretch(拉伸占满显示)、Zoom(按比例缩放显示),初始为Tile。(注:若RightToLeft属性为Yes,则None表示靠右显示)

      (5)Cursor:Cursor型,定义鼠标移动到窗体时显示的光标,初始为Default。

      (6)Font:Font型,定义窗体标题的字体和字号,初始为宋体,9pt。

      (7)ForeColor:Color型,定义窗体标题的颜色,初始为系统颜色ControlText。

      (8)FormBorderStyle:定义窗体的边框和标题栏的外观,获取或设置窗体的边框样式,默认值为Sizable。可以通过设置该属性值为none,实现隐藏窗体标题栏的功能。
      可选属性值如下表:

      属性值 说明
      None 窗体无边框
      FixedSingle 固定的单行边框
      Fixed3D 固定的三维边框
      FixedDialog 固定的对话框式的粗边框
      Sizable 可调整大小的边框
      FixedToolWindow 固定大小的工具窗口边框
      SizableToolWindow 可调整大小的工具窗口边框

      (注:若将此属性调为Fixed开头的属性,那么运行后窗体尺寸将不可通过鼠标拖动修改)

      (9)RightToLeft:RightToLeft枚举型,定义窗体是否从右往左绘制,枚举值有Yes(从右往左绘制)、No(从左往右绘制)、Inherit(继承当前,通常是从左往右绘制),初始为No。

      (10)RightToLeftLayout:bool型,指示窗体布局是否从右往左,初始为false。(注:当RightToLeft属性设置为Yes的时候,这个属性才起作用)

    5. 行为属性

      (1)ContextMenuStrip:(后续讲)定义用户右击窗体时显示的快捷菜单,初始为空。(注:若要创建此菜单,需要写代码创建或者拖动创建ContextMenuStrip控件后再选择这里,无法在属性框直接创建)。

      (2)Enabled:bool型,指示是否启用该窗体,初始为true。(注:将该属性设置为false,窗体内的所有控件都将变灰,为不可用状态)

      (3)AllowDrop:用来获取或设置一个值,该值指示窗口是否可以接受用户拖放到它上面的数据。默认值为False。

      (4)ImeMode:获取或设置控件的输入法编辑器IME模式。

    6. 其他属性

      (1)KeyPreview:bool型,指示窗体是否接收键盘事件,初始为false。(注:这个属性若为ture,窗体将接收键盘事件(包括KeyPress,KeyDown,KeyUp事件),若为false,则窗体内选定的控件接收键盘事件)

      (2)AcceptButton:该属性用来获取或设置一个值,该值是一个按钮的名称,当按【Enter】键时就相当于单击了窗体上的该按钮。

      (3)CancelButton:该属性用来获取或设置一个值,该值是一个按钮的名称,当按【Esc】键时就相当于单击了窗体上的该按钮。

  3. 窗体常用方法:

    (1)Show:让窗体显示出来

    1
    2
    3
    4
    5
    //例如使用show方法显示Form1窗体

    From1 frm = new Form1();

    frm.Show();

    (2)ShowDialog:将窗口显示为模态对话框(在该模态窗口关闭之前,该父窗口不能成为活动窗口,除非关闭该模态窗口)

    1
    2
    3
    From1 frm = new Form1();

    frm.ShowDialog();

    模态对话框在显示之后,就不能对同一个程序中的其它窗口进行操作。非模态对话框在显示之后,还可以对同一个程序的其它窗口进行操作。

    (3)Hide:把窗体隐藏起来,但不销毁窗体,也不释放资源,可以使用Show方法重新显示。

    1
    2
    3
    From1 frm = new Form1();

    frm.Hide();

    (4)Close:把窗体关闭。

    1
    2
    3
    From1 frm = new Form1();

    frm.Close();

    (5)Refresh:刷新并重画窗体。

    1
    2
    3
    From1 frm = new Form1();

    frm.Refresh();

    (6)Activate:激活窗体并给予它焦点。

    1
    2
    3
    From1 frm = new Form1();

    frm.Activate();

窗体常用事件

(1)Load:加载窗体事件,加载窗体时候发生,是窗体的双击默认事件。(注:该事件在创建后,显示前调用,双击窗体可直接注册该事件,并自动转到该事件的方法体)

(2)Shown:窗体显示事件,窗体第一次显示时候发生。(注:该事件在显示后调用,即Show()或者ShowDialog()后发生)

(3)FormClosing:窗体正在关闭(关闭前)事件,窗体正在关闭(关闭前)发生。(注:FormClosing事件可以阻止窗体关闭,而FormClosed无法阻止)

(4)FormClosed:窗体已关闭事件,窗体已关闭发生。

(5)Click、MouseClick 事件:该事件在用户单击窗体时发生。

(6)DoubleClick 事件:该事件在用户双击窗体时发生。

(7)Resize 事件:该事件在改变窗体大小时发生。

(8)Paint 事件:该事件在重绘窗体时发生。

(9)Activated 事件:窗体得到焦点后,即窗口激活时将引发该事件。

(10)Deactivate 事件:窗体失去焦点后,成为不活动窗体时将引发该事件。

(11)TextChanged 事件:窗体的标题文本被更改时将引发该事件。

(12)LocationChanged 事件:窗体的位置被更改时将引发该事件。

(13)SizeChanged 事件:窗体的大小被更改时将引发该事件。

(14)BackClolorChanged 事件:窗体的背景颜色被更改时将引发该事件。

(15)FontChanged 事件:窗体的字体被更改时将引发该事件。

使用控件设计窗体

  1. 设计登录窗体,效果图如下:

    1714378558315

  2. 常用控件及命名规范

    规范化命名可以提高程序的可读性和可维护性

    控件名称 控件类名 命名前缀
    标签 Label lbl
    文本框 TextBox txt
    组合框 ComboBox cbo
    按钮 Button btn
  3. 编写事件

    1. 什么是事件?

      事件驱动:随时响应用户触发的事件,做出相应的处理。

      我们需要做的:针对相关事件,编写相应的事件处理程序

    2. 编写事件的步骤:

      1714378813245

    3. 实现功能,点击“取消”按钮,关闭登录窗体:

      1. 鼠标选中“取消”按钮,选中Click事件,双击生成代码如下 :

        1
        2
        3
        4
        5
        private void btnCancel_Click(object sender, EventArgs e)
        {
        this . Close();//关闭窗体
        }

      2. 具体说明:

        1714379323202

    4. 演示案例,实现以下功能,点击窗体更换窗体颜色。

      1. 需求说明:

        打开窗体为绿色,当鼠标在窗体上点击时,窗体的背景色改变如果是红色,变成黄色如果是黄色,变成绿色;否则变成红色

      2. 效果图:

        打开窗体效果:

        1714379677438

        点击窗体后的效果:

        1714379721942

      3. 实现代码如下 :

        1. 在窗体加载事件中加入代码:

          1
          2
          3
          4
          private void FrmColor_Load(object sender, EventArgs e)
          {
          this.BackColor=Color.Green;
          }
        2. 在点击事件中加入代码:

          1
          2
          3
          4
          private void FrmColor_Click(object sender, EventArgs e)
          {
          this.BackColor = Color.Red;
          }
        3. 实现每点一次修改一次颜色,在点击事件中修改代码实现:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          private void FrmColor_Click(object sender, EventArgs e)
          {
          if (this.BackColor==Color.Yellow)
          {
          this.BackColor = Color.Red;
          }
          else if (this.BackColor==Color.Red)
          {
          this.BackColor = Color.Blue;
          }
          else
          {
          this.BackColor = Color.Yellow;
          }

          }

消息框

  1. 为什么要使用消息框?

    1. 为了显示相关信息

    2. 可以和用户进行交互,向用户请求信息

      1714380213758

  2. 怎么使用消息框?

    使用MessageBox对象

    1714380269014

  3. 4种消息框

    1. 最简单的消息框

      1
      MessageBox.Show("确定退出吗?");

      效果图如下:

      1714380665599

    2. 带标题的消息框:

      1
      MessageBox.Show("确定退出吗?","退出提示");

      效果图如下:

      1714380801960

    3. 带标题和按钮的消息框

      1. MessageBoxButtons:

        在C#中,MessageBoxButtons是一个枚举类型,用于指定在消息框中显示的按钮组合。这个枚举类型是System.Windows.Forms.MessageBoxButtons的一部分,通常在创建Windows窗体应用程序时使用。

        该枚举包含以下值:

        OK,显示”确定“按钮

        OKCancel,显示“确定”和“取消”

        AbortRetryIgnore,显示“中止”,“重试”或“忽略”

        YesNoCancel,显示“是”,“否”或“取消”

        YesNo,显示“是”,“否

        RetryCancel,显示“重试”,“取消”

        Cancel,显示 “取消”

        None

      2. 示例代码:

        1
        MessageBox.Show("确定要退出吗?", "退出提示", MessageBoxButtons.OKCancel);
      3. 效果图如下:

        1714380921251

    4. 带标题,按钮和图标的消息框

      1. MessageBoxIcon:

        在C#中,MessageBoxIcon是一个枚举(enum)类型,用于指定在窗体消息框中显示的图标样式。

        MessageBoxIcon.Error 显示一个带有叉形底色的圆

        MessageBoxIcon.Question 显示一个带有圆形底色的圆

        MessageBoxIcon.Warning 显示一个带有黄色三角形底色的圆

        MessageBoxIcon.Information 显示一个带有蓝色圆形底色的圆

      2. 示例代码:

        1
        MessageBox.Show("确定要退出吗?", "退出提示", MessageBoxButtons.OKCancel,MessageBoxIcon.Question);
      3. 效果图如下:

        1714380999270

消息框的返回值

  1. 当消息框有几个按钮时,如何确定用户点击了哪个按钮呢?

    1714382110325

  2. 查看MessageBox.Show()方法,此方法返回的对象为:DialogResult

    1714382207726

  3. DialogResult的相关知识:

    DialogResult 是一个在 C# 窗体应用程序中常用的枚举类型,它主要用于设置或返回窗体的关闭值。这个值表示窗体的关闭状态,是一个枚举类型,包含以下几种值:

    ​ DialogResult.None:没有设置特定的返回值,默认情况下,对话框的返回值为 None。

    ​ DialogResult.OK:表示用户已经同意执行操作,或者操作已经成功完成。

    ​ DialogResult.Cancel:表示用户想要取消当前的操作。

    ​ DialogResult.Abort:表示用户想要终止操作。

    ​ DialogResult.Retry:表示用户想要重试操作。

    ​ DialogResult.Ignore:表示用户想要忽略操作的警告或错误。

    ​ DialogResult.Yes:表示用户想要执行操作并且答案是“是”。

    ​ DialogResult.No:表示用户想要执行操作并且答案是“否”。

  4. 示例代码:

    1
    2
    3
    4
    5
    DialogResult result = MessageBox.Show("确认取消登录吗?", "操作提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
    if (result == DialogResult.Yes)
    {
    this.Close();
    }

窗体控件输入数据的验证

  1. 具体验证要求:
    1. 用户名不能为空
    2. 密码不能为空,且密码长度必须为6-18位之间
    3. 登录类型必须选择

1714383054414

  1. 编写验证输入内容的方法,返回为bool类型:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public bool CheckInput()
    {
    // 获得文本框的值,判断是否为空
    if (this.txtUserName.Text.Trim().Equals(string.Empty))
    {
    MessageBox.Show("请输入用户名", "验证提示",
    MessageBoxButtons.OK, MessageBoxIcon.Information);
    this.txtUserName.Focus();//光标定位到输入框中
    return false;
    }
    else if (this.txtPwd.Text.Trim().Equals(string.Empty))
    {
    MessageBox.Show("请输入密码", "验证提示",
    MessageBoxButtons.OK, MessageBoxIcon.Information);
    this.txtPwd.Focus();//光标定位到输入框中
    return false;
    }
    else if (this.txtPwd.Text.Trim().Length<8&& this.txtPwd.Text.Trim().Length>16)
    {
    MessageBox.Show("密码长度必须在8-16之间!", "验证提示",
    MessageBoxButtons.OK, MessageBoxIcon.Information);
    this.txtPwd.Focus();//光标定位到输入框中
    return false;
    }
    else if (this.cboLoginType.SelectedIndex==0)
    {
    MessageBox.Show("请选择登录方式!", "验证提示",
    MessageBoxButtons.OK, MessageBoxIcon.Information);
    return false;
    }

    return true;
    }
  2. 登录时调用验证方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    private void btnLogin_Click(object sender, EventArgs e)
    {
    if (CheckInput()) // 输入验证通过
    {
    //验证通过后,再实现登录功能
    ..........
    }
    }

窗体之间传参

  1. 问题:当登录成功后,如何在主窗体显示登录框输入的用户名?

    如何将登录窗体的文本框内容,传入到另一个窗体(主窗体)中去使用,涉及到二个窗体之间的传参。

  2. 窗体之间传参的几种方式:

    1. 方式一:

      思路:在另一个窗体(主窗体)中加入一个公共字段,打开此窗体时直接赋值,在主窗体中调用些公共字段。

      具体实现:

      1. 在主窗体中加入公共字段

        1
        2
        3
        4
        5
        6
        7
        8
        9
        public partial class FrmTwo : Form
        {
        //接受数据的字段
        public string text;
        public FrmTwo()
        {
        InitializeComponent();
        }
        }
      2. 在主窗体加载事件中调用授受数据的字段

        1
        2
        3
        4
        private void FrmTwo_Load(object sender, EventArgs e)
        {
        lblText.Text = text;
        }
      3. 在登录窗体,打开主窗体时,给公共字段赋值

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        public partial class FrmLogin : Form
        {
        public FrmLogin()
        {
        InitializeComponent();
        }

        private void btnClick_Click(object sender, EventArgs e)
        {
        //打开新窗体
        FrmTwo frm = new FrmTwo();
        frm.text=txtContent.Text;//给公共字段赋值,实现数据传递
        frm.Show();
        }
        }
    2. 方式二:

      思路:控件也是窗体对象的属性,我们可以加入公共字段,那么能否将控件属性设置为公共属性呢?

      具体实现:

      1. 将主窗体的Label控件设置为public,如图:

        1714442413286

      2. 在登录窗口,直接给主窗体label控件赋值 :

        1
        2
        3
        4
        5
        6
        7
        private void btnClick_Click(object sender, EventArgs e)
        {
        //打开新窗体
        FrmTwo frm = new FrmTwo();
        frm.lblText.Text =txtContent.Text;//将输入内容直接赋值给主窗体label控件
        frm.Show();
        }
    3. 方式三:

      思路:大家想想,二个变量的数据交换是怎么实现?是通过中间变量来实现

      1
      2
      3
      4
      int num1=10,num2=20;
      int temp=num1;//将一变量数据存入在临时变量中
      num1=num2;
      num2=temp;

      那么二个窗体之间传数据,可否使用中间类来实现呢?

      具体实现:

      1. 创建中间类

        1
        2
        3
        4
        public class Temp
        {
        public static string userId;//使用静态变量来接受
        }
      2. 在登录窗口给中间类的静态变量赋值

        1
        2
        3
        4
        5
        6
        7
        8
        private void btnClick_Click(object sender, EventArgs e)
        {
        //打开新窗体
        FrmTwo frm = new FrmTwo();

        Temp.userId=txtContent.Text;//将数据赋值给中间类的变量
        frm.Show();
        }
      3. 在主窗体使用中间类的静态变量

        1
        2
        3
        4
        private void FrmTwo_Load(object sender, EventArgs e)
        {
        lblText.Text = Temp.userId;
        }

课后作业

1.模拟游戏控制角色移动与闪现

2.模拟病毒攻击:循环弹窗50次,位置随机,背景颜色随机。且窗口无边框,不能关闭。

3.实现登录功能,且在登录成功后显示登录信息。

4.实现两个窗体互相控制移动的功能。