本课学习目标
- 理解什么是事件驱动(Event-driven)程序。
- 认识事件(Event)与事件处理程序(Event Handler)的关系。
- 看懂 Private Sub ... End Sub 的基本结构。
- 理解 Handles btnSave.Click 的作用。
- 初步认识 sender 与 EventArgs。
- 认识 Click、TextChanged、CheckedChanged、SelectedIndexChanged、Load 等常用事件。
- 完成一个能响应多种用户操作的“事件体验器”。
4.1 什么是事件驱动编程?
Windows Forms 属于典型的事件驱动应用。程序大部分时间都在等待,当某件事情发生时,才执行与该事件连接的代码。
例如,用户点击“显示”按钮时,按钮产生 Click 事件。Visual Basic 会执行我们为这个 Click 事件编写的事件处理程序,然后程序可以改变标签文字、清除输入或执行其他工作。
4.2 什么是事件(Event)?
事件可以理解为“对象发出的通知”:某件值得程序注意的事情发生了。
Click被点击
常见于 Button,也可发生在许多其他控件上。
TextChanged文字改变
TextBox 或其他具有 Text 的控件内容改变时发生。
CheckedChanged勾选状态改变
CheckBox 或 RadioButton 的 Checked 状态改变时发生。
SelectedIndexChanged选择项目改变
ComboBox 或 ListBox 的当前选择改变时发生。
Load窗体加载
窗体准备显示时发生,常用来执行初始化工作。
FormClosing窗体准备关闭
可以在关闭前检查状态或询问用户是否真的要退出。
4.3 什么是事件处理程序?
事件本身只是表示“某件事发生了”。真正要执行的工作写在事件处理程序里。
第 2 课曾经使用过这段代码:
Private Sub btnGreet_Click(sender As Object, e As EventArgs) Handles btnGreet.Click
lblResult.Text = "按钮被点击了。"
End Sub
这整个 Sub 就是一个事件处理程序。它与 btnGreet.Click 事件连接,因此按钮被点击时,里面的代码就会执行。
4.4 Sub 与 VB.NET 代码区块
Visual Basic 使用清楚的开始与结束关键字组成代码区块。例如一个 Sub 从 Sub 开始,以 End Sub 结束。
Private Sub btnHello_Click(sender As Object, e As EventArgs) Handles btnHello.Click
' 这里是事件发生时要执行的代码
lblMessage.Text = "你好!"
End Sub
代码中的单引号 ' 表示注释。注释是写给程序员看的说明,编译器不会把它当成要执行的指令。
4.5 Handles:把事件与代码连接起来
下面最重要的部分是:
Handles btnHello.Click
它可以读成:“这个 Sub 负责处理 btnHello 的 Click 事件。”
完整示例:
Private Sub btnHello_Click(sender As Object, e As EventArgs) Handles btnHello.Click
lblMessage.Text = "欢迎学习 Visual Basic 2026!"
End Sub
如果按钮的 Name 是 btnHello,并且处理程序使用 Handles btnHello.Click,当用户点击这个按钮时,VB.NET 就知道要执行哪个 Sub。
4.6 sender 与 EventArgs 是什么?
Visual Studio 自动建立事件处理程序时,通常会看到两个参数:
sender As Object, e As EventArgs
谁触发了事件?
sender 通常指向触发该事件的对象。简单程序中经常不需要直接使用它。
事件附带的资料
e 保存事件相关信息。一般事件常使用 EventArgs;某些事件会使用更具体的类型。
例如 FormClosing 事件使用的参数类型可以提供“是否取消关闭”等额外资料;键盘事件也会有与按键有关的事件参数。现阶段只需先认识它们的角色。
4.7 在 Visual Studio 中建立事件处理程序
建立事件处理程序最简单的方法有两种。
方法一:双击控件
- 在 Form Designer 中选中 Button。
- 双击 Button。
- Visual Studio 会打开代码编辑器。
- 它通常会自动建立 Button 的默认事件——Click。
方法二:使用 Properties 的事件列表
- 在设计器中选中控件。
- 打开 Properties Window。
- 切换到事件列表(闪电图标)。
- 找到想处理的事件,例如 TextChanged。
- 双击事件名称右侧的空白位置。
第二种方法特别适合处理不是默认事件的情况,例如 CheckBox 的 CheckedChanged 或 Form 的 Load。
4.8 常用事件代码示例
Button.Click
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
lblStatus.Text = "你点击了按钮。"
End Sub
TextBox.TextChanged
Private Sub txtMessage_TextChanged(sender As Object, e As EventArgs) Handles txtMessage.TextChanged
lblPreview.Text = txtMessage.Text
End Sub
这个事件会在文字改变时执行,因此可以制作“即时预览”。
CheckBox.CheckedChanged
Private Sub chkShowPreview_CheckedChanged(sender As Object, e As EventArgs) _
Handles chkShowPreview.CheckedChanged
lblPreview.Visible = chkShowPreview.Checked
End Sub
CheckBox 被勾选时 Checked 是 True;取消勾选时是 False。这里直接把这个值交给 Label 的 Visible 属性。
ComboBox.SelectedIndexChanged
Private Sub cmbCourse_SelectedIndexChanged(sender As Object, e As EventArgs) _
Handles cmbCourse.SelectedIndexChanged
lblCourseResult.Text = "你选择了:" & cmbCourse.Text
End Sub
Form.Load
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblStatus.Text = "程序已经启动。"
End Sub
4.9 看懂 Form1.vb 的基本结构
当你打开 Form1.vb 时,多个事件处理程序通常都位于同一个 Form1 类里面:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblStatus.Text = "程序已经启动。"
End Sub
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
lblStatus.Text = "你点击了显示按钮。"
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
txtMessage.Clear()
lblPreview.Text = ""
End Sub
End Class
现阶段只要掌握:事件处理程序必须写在 Form1 类的内部,而不是放在 End Class 之后。关于“类”本身的完整概念会在后面的面向对象课程再详细学习。
4.10 实作:制作“事件体验器”
新建一个 Windows Forms 项目,名称设为 EventExplorer2026。这个小程序会让你一次体验 TextChanged、CheckedChanged、SelectedIndexChanged 和 Click。
在 Form1 中加入以下控件:
| 控件 | Name | Text / 设置 |
|---|---|---|
| Form | Form1 | Text = Event Explorer 2026 |
| TextBox | txtMessage | 留空 |
| Label | lblPreview | 留空 |
| ComboBox | cmbCourse | 加入:VB.NET 基础、Windows Forms、数据库 |
| Label | lblCourseResult | 留空 |
| CheckBox | chkShowPreview | Text = 显示预览;Checked = True |
| Button | btnShow | Text = 显示状态 |
| Button | btnClear | Text = 清除 |
| Label | lblStatus | 留空 |
完整的 Form1.vb 事件代码
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblStatus.Text = "程序已经启动。"
End Sub
Private Sub txtMessage_TextChanged(sender As Object, e As EventArgs) _
Handles txtMessage.TextChanged
lblPreview.Text = txtMessage.Text
End Sub
Private Sub chkShowPreview_CheckedChanged(sender As Object, e As EventArgs) _
Handles chkShowPreview.CheckedChanged
lblPreview.Visible = chkShowPreview.Checked
End Sub
Private Sub cmbCourse_SelectedIndexChanged(sender As Object, e As EventArgs) _
Handles cmbCourse.SelectedIndexChanged
lblCourseResult.Text = "你选择了:" & cmbCourse.Text
End Sub
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
lblStatus.Text = "显示状态按钮被点击了。"
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
txtMessage.Clear()
lblPreview.Text = ""
lblCourseResult.Text = ""
lblStatus.Text = "内容已经清除。"
End Sub
End Class
4.11 逐个测试事件
- 按 F5 运行程序,确认状态显示“程序已经启动。”——这来自 Load 事件。
- 在 txtMessage 输入文字,观察 lblPreview 是否立即同步——这是 TextChanged。
- 取消“显示预览”的勾选,观察 lblPreview 是否隐藏——这是 CheckedChanged。
- 从 ComboBox 选择课程,观察课程结果文字——这是 SelectedIndexChanged。
- 点击“显示状态”,确认 lblStatus 改变——这是 Click。
- 点击“清除”,确认输入与结果被清除——这是另一个 Click 事件。
完成这些测试后,你已经不只是“会写按钮代码”,而是开始理解 Windows Forms 的核心运行模式。
4.12 初学者常见问题
点击按钮没有反应
检查事件处理程序是否真的带有 Handles btnName.Click,并确认控件 Name 与代码一致。
代码写在 End Class 之后
事件处理程序必须位于 Public Class Form1 与 End Class 之间。
事件触发次数比预期多
TextChanged 会在文字每次改变时触发,并不是等用户“输入完成”才触发。
双击控件建立了错误事件
双击通常建立默认事件。若需要其他事件,请使用 Properties Window 的事件列表选择。
4.13 小练习:增加更多事件
在 EventExplorer2026 中尝试以下扩展:
- 加入 Button:btnWelcome,Text 设置为“欢迎”。点击后把 lblStatus 改为“欢迎来到 Visual Basic 2026!”
- 加入另一个 CheckBox:chkEnableInput。在 CheckedChanged 事件中,把 txtMessage.Enabled 设置为 chkEnableInput.Checked。
- 尝试在 Form 的 Load 事件中预先设置 cmbCourse.Text。
- 把不同事件处理程序按“窗体事件、输入事件、按钮事件”的顺序排列,让代码更容易阅读。
本课复习
- 什么是事件驱动编程?
- 事件与事件处理程序有什么不同?
- Sub 和 End Sub 的作用是什么?
- Handles btnSave.Click 表示什么?
- sender 一般代表什么?
- e As EventArgs 的作用是什么?
- TextBox 的 TextChanged 与 Button 的 Click 分别在什么时候发生?
- 事件处理程序应该写在 Form1 类的哪个位置?