VB Visual Basic 2026 中文教程
第 20 课 · 专业桌面界面

菜单、工具栏与状态栏

Windows 桌面应用通常不只依赖按钮。菜单负责组织完整命令,工具栏提供常用操作的快速入口,状态栏则持续告诉用户当前文件、字数或程序状态。本课将学习 MenuStrip、ToolStrip 和 StatusStrip,并把上一课的迷你文本编辑器升级成更完整的桌面应用。

适合:完成第 19 课的初学者建议时间:60–75 分钟实作:MiniTextEditorPro2026

本课学习目标

  • 认识 MenuStripToolStripStatusStrip
  • 建立 File、Edit、Format、Help 等主菜单。
  • 使用 ToolStripMenuItem 建立菜单命令。
  • 设置菜单快捷键 ShortcutKeys
  • 使用分隔线整理菜单。
  • 建立 ToolStripButton 常用操作。
  • 让菜单和工具栏重用同一组方法。
  • 使用 ToolStripStatusLabel 显示状态。
  • 在 TextChanged 事件中更新字数。
  • 使用项目资源为工具栏按钮提供图标。
  • 完成专业版迷你文本编辑器。

20.1 三种常见界面组件

MenuStrip、ToolStrip 和 StatusStrip 各自负责不同任务,组合起来可以让 Windows Forms 应用更接近专业桌面软件。

MenuStrip

菜单栏

按类别组织完整功能,例如 File、Edit、Format、Help。

ToolStrip

工具栏

为打开、保存、剪切等常用功能提供快速按钮。

StatusStrip

状态栏

显示当前文件、字符数、状态消息等持续信息。

Mini Text Editor Pro 2026
NewOpenSaveCutCopyPaste
这里是文本编辑区域。菜单栏提供完整命令,工具栏提供常用快捷操作。
ReadyCharacters: 35

从 Toolbox 拖入:

MenuStrip

将名称设为:

menuMain

然后建立主菜单:

File
Edit
Format
Help

每一个项目实际上都是 ToolStripMenuItem

menuMain
整个 MenuStrip。
mnuFile
File 主菜单。
mnuFileOpen
File → Open 命令。
mnuFileSave
File → Save 命令。

File 菜单可以包含:

New
Open...
Save...
----------------
Exit

建议 Name:

菜单文字Name
NewmnuFileNew
Open...mnuFileOpen
Save...mnuFileSave
ExitmnuFileExit

20.4 使用菜单分隔线

菜单中的横线是 ToolStripSeparator,用来把相关命令分组。

New
Open
Save
------------
Exit
不要让菜单成为一长串没有结构的命令 通过分隔线把“文件操作”和“退出程序”分开,用户更容易找到功能。

20.5 设置 ShortcutKeys

桌面应用常用快捷键:

Ctrl+N建立新文件
Ctrl+O打开文件
Ctrl+S保存文件
Ctrl+X剪切
Ctrl+C复制
Ctrl+V粘贴

在 Properties Window 中选择菜单项目,例如 mnuFileSave,设置:

ShortcutKeys = Ctrl + S

设置之后,即使用户不打开菜单,也可以直接按 Ctrl+S 触发菜单命令。

20.6 Edit 菜单

TextBox 本身已经提供:

txtEditor.Cut()
txtEditor.Copy()
txtEditor.Paste()
txtEditor.SelectAll()

因此菜单事件可以非常简单:

Private Sub mnuEditCut_Click(
    sender As Object,
    e As EventArgs) Handles mnuEditCut.Click

    txtEditor.Cut()

End Sub

复制:

Private Sub mnuEditCopy_Click(
    sender As Object,
    e As EventArgs) Handles mnuEditCopy.Click

    txtEditor.Copy()

End Sub

粘贴:

Private Sub mnuEditPaste_Click(
    sender As Object,
    e As EventArgs) Handles mnuEditPaste.Click

    txtEditor.Paste()

End Sub

20.7 建立 ToolStrip

从 Toolbox 加入:

ToolStrip

名称:

toolMain

然后加入 ToolStripButton:

功能Name建议 Text
新建tsbNewNew
打开tsbOpenOpen
保存tsbSaveSave
剪切tsbCutCut
复制tsbCopyCopy
粘贴tsbPastePaste

20.8 工具栏图标

ToolStripButton 可以设置 Image。固定图标适合加入项目 Resources:

tsbOpen.Image = My.Resources.OpenIcon
tsbSave.Image = My.Resources.SaveIcon

也可以直接在 Designer 中为 ToolStripButton 的 Image 属性选择资源。

延续第 18 课的 Resources 工具栏图标通常属于固定应用素材,因此很适合嵌入 Resources,而不是依赖用户电脑上的外部图片路径。

20.9 菜单和工具栏不要复制相同代码

如果菜单 Open 和工具栏 Open 都要打开文件,不应该复制两份完整逻辑。

先建立方法:

Private Sub OpenTextFile()

    dlgOpen.Filter =
        "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*"

    If dlgOpen.ShowDialog() =
        DialogResult.OK Then

        txtEditor.Text =
            File.ReadAllText(
                dlgOpen.FileName)

        currentFilePath =
            dlgOpen.FileName

        UpdateStatus(
            "已打开文件。")

    End If

End Sub

菜单调用:

Private Sub mnuFileOpen_Click(
    sender As Object,
    e As EventArgs) Handles mnuFileOpen.Click

    OpenTextFile()

End Sub

工具栏也调用:

Private Sub tsbOpen_Click(
    sender As Object,
    e As EventArgs) Handles tsbOpen.Click

    OpenTextFile()

End Sub
菜单 OpenClick
OpenTextFile()统一逻辑
OpenFileDialog选择文件
读取并显示File.ReadAllText

20.10 建立 StatusStrip

从 Toolbox 加入:

StatusStrip

名称:

statusMain

再加入两个 ToolStripStatusLabel

lblStatus
lblCharCount

例如:

lblStatus.Text = "Ready"
lblCharCount.Text = "Characters: 0"

20.11 自定义 UpdateStatus 方法

Private Sub UpdateStatus(
    message As String)

    lblStatus.Text =
        message

End Sub

以后各个功能都可以调用:

UpdateStatus("文件保存成功。")

20.12 自动更新字符数量

TextBox 的 TextChanged 事件会在文字改变时触发:

Private Sub txtEditor_TextChanged(
    sender As Object,
    e As EventArgs) Handles txtEditor.TextChanged

    lblCharCount.Text =
        $"Characters: {txtEditor.Text.Length}"

End Sub

这样用户输入、粘贴、打开文件或清除内容时,状态栏都会自动更新。

20.13 让状态栏项目分开排列

如果希望左边显示状态、右边显示字数,可以把第一个 ToolStripStatusLabel 的:

Spring = True

并将:

TextAlign = MiddleLeft

这样第一个 Label 会自动占用剩余空间,把第二个 Label 推到右侧。

20.14 实作:Mini Text Editor Pro 2026

建立新的 Windows Forms 项目:

MiniTextEditorPro2026

这个项目延续 Lesson 19,但将按钮式界面升级为菜单栏、工具栏和状态栏结构。

Mini Text Editor Pro 2026 - note.txt
NewOpenSaveCutCopyPaste
欢迎使用 Mini Text Editor Pro 2026。

支持菜单、工具栏、状态栏、打开、保存、字体、颜色和快捷键。
ReadyCharacters: 88

Form1 主要组件:

组件Name用途
MenuStripmenuMainFile / Edit / Format / Help
ToolStriptoolMain常用快捷按钮
TextBoxtxtEditorMultiline = True;Dock = Fill
StatusStripstatusMain状态和字数
ToolStripStatusLabellblStatus当前状态;Spring = True
ToolStripStatusLabellblCharCount字符数量
OpenFileDialogdlgOpen打开文件
SaveFileDialogdlgSave保存文件
FontDialogdlgFont选择字体
ColorDialogdlgColor选择文字颜色

Form1.vb 顶部

Imports System.IO

Public Class Form1

    Private currentFilePath As String = ""

新建文件方法

Private Sub NewDocument()

    If txtEditor.Text.Length > 0 Then

        Dim result As DialogResult =
            MessageBox.Show(
                "建立新文件会清除当前内容。是否继续?",
                "新建文件",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question)

        If result <> DialogResult.Yes Then
            Exit Sub
        End If

    End If

    txtEditor.Clear()
    currentFilePath = ""

    Me.Text =
        "Mini Text Editor Pro 2026 - Untitled"

    UpdateStatus(
        "已建立新文件。")

End Sub

打开文件方法

Private Sub OpenTextFile()

    dlgOpen.Filter =
        "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*"

    dlgOpen.Title =
        "打开文本文件"

    If dlgOpen.ShowDialog() <>
        DialogResult.OK Then

        Exit Sub

    End If

    txtEditor.Text =
        File.ReadAllText(
            dlgOpen.FileName)

    currentFilePath =
        dlgOpen.FileName

    Me.Text =
        "Mini Text Editor Pro 2026 - " &
        Path.GetFileName(
            currentFilePath)

    UpdateStatus(
        "文件打开成功。")

End Sub

保存文件方法

Private Sub SaveTextFile()

    If String.IsNullOrWhiteSpace(
        currentFilePath) Then

        dlgSave.Filter =
            "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*"

        dlgSave.DefaultExt =
            "txt"

        dlgSave.FileName =
            "note.txt"

        If dlgSave.ShowDialog() <>
            DialogResult.OK Then

            Exit Sub

        End If

        currentFilePath =
            dlgSave.FileName

    End If

    File.WriteAllText(
        currentFilePath,
        txtEditor.Text)

    Me.Text =
        "Mini Text Editor Pro 2026 - " &
        Path.GetFileName(
            currentFilePath)

    UpdateStatus(
        "文件保存成功。")

End Sub

菜单事件

Private Sub mnuFileNew_Click(
    sender As Object,
    e As EventArgs) Handles mnuFileNew.Click

    NewDocument()

End Sub

Private Sub mnuFileOpen_Click(
    sender As Object,
    e As EventArgs) Handles mnuFileOpen.Click

    OpenTextFile()

End Sub

Private Sub mnuFileSave_Click(
    sender As Object,
    e As EventArgs) Handles mnuFileSave.Click

    SaveTextFile()

End Sub

工具栏事件重用相同方法

Private Sub tsbNew_Click(
    sender As Object,
    e As EventArgs) Handles tsbNew.Click

    NewDocument()

End Sub

Private Sub tsbOpen_Click(
    sender As Object,
    e As EventArgs) Handles tsbOpen.Click

    OpenTextFile()

End Sub

Private Sub tsbSave_Click(
    sender As Object,
    e As EventArgs) Handles tsbSave.Click

    SaveTextFile()

End Sub

剪切、复制、粘贴

Private Sub mnuEditCut_Click(
    sender As Object,
    e As EventArgs) Handles mnuEditCut.Click

    txtEditor.Cut()

End Sub

Private Sub mnuEditCopy_Click(
    sender As Object,
    e As EventArgs) Handles mnuEditCopy.Click

    txtEditor.Copy()

End Sub

Private Sub mnuEditPaste_Click(
    sender As Object,
    e As EventArgs) Handles mnuEditPaste.Click

    txtEditor.Paste()

End Sub

ToolStrip 的 Cut、Copy、Paste 按钮也可以直接调用对应 TextBox 方法,或者进一步拆成共用 Sub。

字体菜单

Private Sub mnuFormatFont_Click(
    sender As Object,
    e As EventArgs) Handles mnuFormatFont.Click

    dlgFont.Font =
        txtEditor.Font

    If dlgFont.ShowDialog() =
        DialogResult.OK Then

        txtEditor.Font =
            dlgFont.Font

        UpdateStatus(
            "字体已经更新。")

    End If

End Sub

文字颜色菜单

Private Sub mnuFormatColor_Click(
    sender As Object,
    e As EventArgs) Handles mnuFormatColor.Click

    dlgColor.Color =
        txtEditor.ForeColor

    If dlgColor.ShowDialog() =
        DialogResult.OK Then

        txtEditor.ForeColor =
            dlgColor.Color

        UpdateStatus(
            "文字颜色已经更新。")

    End If

End Sub

状态更新方法

Private Sub UpdateStatus(
    message As String)

    lblStatus.Text =
        message

End Sub

字符数自动更新

Private Sub txtEditor_TextChanged(
    sender As Object,
    e As EventArgs) Handles txtEditor.TextChanged

    lblCharCount.Text =
        $"Characters: {txtEditor.Text.Length}"

End Sub

退出菜单

Private Sub mnuFileExit_Click(
    sender As Object,
    e As EventArgs) Handles mnuFileExit.Click

    Dim result As DialogResult =
        MessageBox.Show(
            "确定要退出程序吗?",
            "退出",
            MessageBoxButtons.YesNo,
            MessageBoxIcon.Question)

    If result =
        DialogResult.Yes Then

        Me.Close()

    End If

End Sub

20.15 程序结构为什么更好?

1
菜单提供完整功能

用户可以按 File、Edit、Format 找到所有命令。

2
工具栏提供快速入口

最常用功能不需要层层打开菜单。

3
方法集中业务逻辑

OpenTextFile 和 SaveTextFile 不属于某一个按钮专用。

4
状态栏持续反馈

告诉用户文件是否保存,以及当前字符数。

5
快捷键提升效率

熟练用户可以直接 Ctrl+S、Ctrl+O 等操作。

20.16 初学者常见错误

错误 1

菜单和工具栏复制整段代码

相同命令应该调用同一个自定义方法,避免维护两份逻辑。

错误 2

菜单项目 Name 太模糊

不要全部叫 ToolStripMenuItem1。建议 mnuFileOpen、mnuEditCopy 等。

错误 3

快捷键冲突

同一个窗体不要让多个命令使用同一组快捷键。

错误 4

状态栏永远显示 Ready

重要操作完成后应调用 UpdateStatus,让用户知道程序发生了什么。

20.17 小练习

  1. 加入 Edit → Select All,并设置 Ctrl+A。
  2. 为 ToolStrip 的 New、Open、Save 加入 Resources 图标。
  3. 加入状态栏 Label 显示当前文件名称。
  4. 加入 Format → Background Color,改变 txtEditor.BackColor。
  5. 在 Help 菜单加入 About,使用 MessageBox.Show 显示程序名称和版本。
  6. 把 Cut、Copy、Paste 也拆成共用 Sub,让菜单和工具栏完全重用。
  7. 加入 ToolStripSeparator,把文件操作与编辑操作分开。

本课复习

  1. MenuStrip、ToolStrip 和 StatusStrip 分别有什么用途?
  2. 菜单中的单个项目通常是什么类型?
  3. ToolStripSeparator 的作用是什么?
  4. 怎样为菜单设置 Ctrl+S?
  5. 为什么菜单 Open 与工具栏 Open 不应该复制两份打开文件代码?
  6. ToolStripButton 的 Image 适合从哪里取得?
  7. ToolStripStatusLabel 可以显示哪些类型的状态?
  8. TextChanged 为什么适合用来更新字符数?
  9. StatusLabel 的 Spring = True 有什么效果?
  10. 为什么专业桌面应用通常同时提供菜单、工具栏和快捷键?