本课学习目标
- 理解为什么用户输入必须验证。
- 使用 String.IsNullOrWhiteSpace 检查空白输入。
- 理解 CInt、CDbl、CDec 与 TryParse 的差别。
- 使用 Integer.TryParse 安全转换整数。
- 使用 Double.TryParse 与 Decimal.TryParse。
- 把“格式验证”和“范围验证”分开。
- 使用 Exit Sub 在验证失败时停止处理。
- 设计清楚、友好的错误提示。
- 使用 ErrorProvider 的基本方式标记输入错误。
- 完成一个可靠的学生成绩验证器。
13.1 为什么输入验证很重要?
程序不能控制用户输入什么,但可以控制怎样处理用户输入。
假设成绩文本框应该输入 0–100 的整数,但用户可能输入:
""
用户没有输入任何资料。
"abc"
需要数字,却输入了文字。
"150"
虽然是整数,但超过允许的 0–100。
可靠程序应该分辨这些问题,并告诉用户怎样修正,而不是直接崩溃或产生不合理结果。
13.2 为什么不能只依赖 CInt?
之前我们经常写:
Dim score As Integer = CInt(txtScore.Text)
如果用户输入 85,这没有问题。但如果输入:
abc
程序在转换时会失败,并产生异常。
13.3 TryParse 的基本思想
TryParse 会尝试转换,并返回 Boolean 表示是否成功。
Integer.TryParse(txtScore.Text, score)
→
True 或 False
如果成功,转换后的值会放入 score;如果失败,返回 False。
Dim score As Integer
If Integer.TryParse(txtScore.Text, score) Then
lblResult.Text = "有效整数:" & score.ToString()
Else
lblResult.Text = "请输入有效整数。"
End If
13.4 Integer.TryParse
Dim age As Integer
If Integer.TryParse(txtAge.Text, age) Then
lblResult.Text = "年龄:" & age.ToString()
Else
lblResult.Text = "年龄必须是整数。"
End If
常见测试:
| 输入 | TryParse 结果 | age |
|---|---|---|
| 25 | True | 25 |
| -3 | True | -3 |
| 12.5 | False | 转换失败 |
| abc | False | 转换失败 |
| 空白 | False | 转换失败 |
13.5 格式验证之后还要检查范围
Dim score As Integer
If Not Integer.TryParse(txtScore.Text, score) Then
lblResult.Text = "成绩必须是整数。"
Exit Sub
End If
If score < 0 OrElse score > 100 Then
lblResult.Text = "成绩必须介于 0 与 100。"
Exit Sub
End If
lblResult.Text = "成绩有效:" & score.ToString()
“abc”根本不能转换成 Integer,不需要做范围比较。
150 是合法 Integer,但不是合法成绩。
只有 0–100 的整数才进入后续业务逻辑。
13.6 使用 Exit Sub 简化验证流程
验证失败后,通常没有必要继续执行事件处理程序。
If String.IsNullOrWhiteSpace(txtName.Text) Then
lblResult.Text = "请输入学生姓名。"
txtName.Focus()
Exit Sub
End If
Exit Sub 会立即结束当前 Sub。这样可以避免大量嵌套 If。
不推荐:过度嵌套
If Not String.IsNullOrWhiteSpace(txtName.Text) Then
If Integer.TryParse(txtScore.Text, score) Then
If score >= 0 AndAlso score <= 100 Then
' 真正处理
End If
End If
End If
更清楚:失败就提前离开
If String.IsNullOrWhiteSpace(txtName.Text) Then
lblResult.Text = "请输入学生姓名。"
Exit Sub
End If
If Not Integer.TryParse(txtScore.Text, score) Then
lblResult.Text = "请输入有效整数成绩。"
Exit Sub
End If
If score < 0 OrElse score > 100 Then
lblResult.Text = "成绩必须介于 0 与 100。"
Exit Sub
End If
' 验证通过,继续处理
13.7 检查空白文字
对于姓名、课程、编号等文字输入,可以使用:
If String.IsNullOrWhiteSpace(txtStudentName.Text) Then
lblResult.Text = "请输入学生姓名。"
txtStudentName.Focus()
Exit Sub
End If
它会处理:
- 空字符串
- 只包含空格的字符串
- Nothing
因此比单纯:
If txtStudentName.Text = "" Then
更完整。
13.8 Double.TryParse 与 Decimal.TryParse
Double.TryParse
Dim temperature As Double
If Not Double.TryParse(txtTemperature.Text, temperature) Then
lblResult.Text = "请输入有效温度。"
Exit Sub
End If
Decimal.TryParse
Dim price As Decimal
If Not Decimal.TryParse(txtPrice.Text, price) Then
lblResult.Text = "请输入有效价格。"
Exit Sub
End If
| 输入类型 | 建议 TryParse | 例子 |
|---|---|---|
| 人数、数量、成绩 | Integer.TryParse | 25、100 |
| 测量值、科学计算 | Double.TryParse | 36.8、3.14159 |
| 价格、金额 | Decimal.TryParse | 199.90、1250.50 |
13.9 一次验证多个字段
实际表单通常不只一个输入。最简单的初学方式是按顺序逐项验证:
Dim quantity As Integer
Dim unitPrice As Decimal
If String.IsNullOrWhiteSpace(txtProductName.Text) Then
lblResult.Text = "请输入产品名称。"
txtProductName.Focus()
Exit Sub
End If
If Not Integer.TryParse(txtQuantity.Text, quantity) Then
lblResult.Text = "数量必须是整数。"
txtQuantity.Focus()
Exit Sub
End If
If quantity <= 0 Then
lblResult.Text = "数量必须大于 0。"
txtQuantity.Focus()
Exit Sub
End If
If Not Decimal.TryParse(txtUnitPrice.Text, unitPrice) Then
lblResult.Text = "请输入有效单价。"
txtUnitPrice.Focus()
Exit Sub
End If
If unitPrice < 0 Then
lblResult.Text = "单价不能小于 0。"
txtUnitPrice.Focus()
Exit Sub
End If
13.10 使用 MessageBox 显示验证错误
除了 Label,也可以使用 MessageBox:
If Not Integer.TryParse(txtScore.Text, score) Then
MessageBox.Show(
"请输入 0 到 100 之间的整数成绩。",
"输入错误",
MessageBoxButtons.OK,
MessageBoxIcon.Warning)
txtScore.Focus()
Exit Sub
End If
对于重要错误,MessageBox 很醒目;但如果表单中有很多字段,也可以考虑在字段旁边显示错误。
13.11 ErrorProvider 简介
Windows Forms 的 ErrorProvider 可以在控件旁显示错误图标。
从 Toolbox 加入一个 ErrorProvider,名称设为:
errInput
设置错误:
errInput.SetError(txtScore, "请输入有效成绩。")
清除错误:
errInput.SetError(txtScore, "")
例如:
Dim score As Integer
errInput.SetError(txtScore, "")
If Not Integer.TryParse(txtScore.Text, score) Then
errInput.SetError(txtScore, "成绩必须是整数。")
txtScore.Focus()
Exit Sub
End If
13.12 实作:学生成绩验证器
建立新的 Windows Forms 项目:
StudentScoreValidator2026
这个程序让用户输入学生姓名、测验成绩和考试成绩。程序会先完整验证,再计算平均分,并显示等级。
测验:78
考试:86
平均分:82.00
等级:A
在 Form1 加入:
| 控件 | Name | Text / 设置 |
|---|---|---|
| Form | Form1 | Text = 学生成绩验证器 |
| TextBox | txtStudentName | 输入学生姓名 |
| TextBox | txtQuizScore | 输入 0–100 |
| TextBox | txtExamScore | 输入 0–100 |
| Button | btnValidate | Text = 验证并计算 |
| Button | btnClear | Text = 清除 |
| Label | lblResult | 显示验证后结果 |
| ErrorProvider | errInput | 显示字段错误 |
完整的验证与计算代码
Private Sub btnValidate_Click(sender As Object, e As EventArgs) _
Handles btnValidate.Click
errInput.Clear()
lblResult.Text = ""
Dim studentName As String = txtStudentName.Text.Trim()
Dim quizScore As Integer
Dim examScore As Integer
If String.IsNullOrWhiteSpace(studentName) Then
errInput.SetError(txtStudentName, "请输入学生姓名。")
txtStudentName.Focus()
Exit Sub
End If
If Not Integer.TryParse(txtQuizScore.Text, quizScore) Then
errInput.SetError(txtQuizScore, "测验成绩必须是整数。")
txtQuizScore.Focus()
Exit Sub
End If
If quizScore < 0 OrElse quizScore > 100 Then
errInput.SetError(txtQuizScore, "测验成绩必须介于 0 与 100。")
txtQuizScore.Focus()
Exit Sub
End If
If Not Integer.TryParse(txtExamScore.Text, examScore) Then
errInput.SetError(txtExamScore, "考试成绩必须是整数。")
txtExamScore.Focus()
Exit Sub
End If
If examScore < 0 OrElse examScore > 100 Then
errInput.SetError(txtExamScore, "考试成绩必须介于 0 与 100。")
txtExamScore.Focus()
Exit Sub
End If
Dim average As Double = (quizScore + examScore) / 2.0
Dim grade As String
Select Case average
Case Is >= 80
grade = "A"
Case Is >= 70
grade = "B"
Case Is >= 60
grade = "C"
Case Is >= 50
grade = "D"
Case Else
grade = "F"
End Select
lblResult.Text =
$"学生:{studentName}" & Environment.NewLine &
$"测验:{quizScore}" & Environment.NewLine &
$"考试:{examScore}" & Environment.NewLine &
$"平均分:{average:N2}" & Environment.NewLine &
$"等级:{grade}"
End Sub
清除按钮
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
txtStudentName.Clear()
txtQuizScore.Clear()
txtExamScore.Clear()
lblResult.Text = ""
errInput.Clear()
txtStudentName.Focus()
End Sub
13.13 逐步理解验证流程
每次重新验证前先 errInput.Clear(),避免旧提示残留。
文字字段使用 IsNullOrWhiteSpace。
无法转换时立即显示错误并 Exit Sub。
转换成功后再确认 0–100。
到达平均分计算时,程序已经可以信任 quizScore 和 examScore。
13.14 必须测试哪些输入?
| 测试输入 | 预期结果 |
|---|---|
| 姓名空白 | 提示输入学生姓名。 |
| 测验 = abc | 提示成绩必须是整数。 |
| 测验 = -1 | 提示必须介于 0 与 100。 |
| 测验 = 101 | 提示必须介于 0 与 100。 |
| 考试 = 88.5 | 如果设计要求整数,应提示格式错误。 |
| 测验 = 78,考试 = 86 | 成功计算平均分与等级。 |
| 测验 = 0,考试 = 0 | 这是有效边界值,应正常处理。 |
| 测验 = 100,考试 = 100 | 这是有效边界值,应正常处理。 |
13.15 初学者常见错误
只用 TryParse,不检查范围
Integer.TryParse("999") 会成功,但 999 可能不是业务允许的值。
先转换再验证
如果先 CInt 再 TryParse,就失去 TryParse 的安全意义。
忘记 Exit Sub
显示错误后如果继续执行,后面的计算仍可能使用无效数据。
错误信息太笼统
“输入错误”不如“成绩必须介于 0 与 100”明确。
13.16 小练习
- 加入作业成绩 txtAssignmentScore,并验证 0–100。
- 把平均分改成三项成绩平均。
- 加入 Decimal 输入“课程费用”,使用 Decimal.TryParse 并确保费用 ≥ 0。
- 加入 Double 输入“出席率”,要求介于 0 与 100。
- 改用 MessageBox 显示其中一个错误,并比较与 ErrorProvider 的体验。
- 为 txtQuizScore 与 txtExamScore 设置错误后,成功验证时清除对应错误。
- 测试边界值 0、50、80、100 与无效值 -1、101、abc。
本课复习
- 为什么用户输入必须验证?
- CInt 与 Integer.TryParse 的核心差别是什么?
- TryParse 返回什么数据类型?
- 为什么 TryParse 成功后仍可能需要范围检查?
- String.IsNullOrWhiteSpace 适合检查什么?
- Exit Sub 在验证流程中的作用是什么?
- 价格输入通常适合使用哪一种 TryParse?
- ErrorProvider 的作用是什么?
- 对于 0–100 的成绩,应至少测试哪些边界值?