总体要求

  1、掌握Windows窗体和控件的常用属性和事件

  2、掌握常用控件的使用方法,包括按钮Button、文本框Textbox、标签Label、单选按钮RadioButton、复选框CheckBox、组合框ComboBox、图片框PictureBox、分组框GroupBox、面板Panel、选项卡TabControl等控件。

  3、了解窗体与对话框的区别,模态对话框与非模态对话框的区别,熟悉消息框和通用对话框的使用方法。

  4、了解菜单、工具栏、状态栏的作用,掌握MenuStrip、ContextMenuStrip、TooStrip和StatusStrip等控件的使用方法。

  5、理解SDI应用程序和MDI应用程序的区别,学会创建较为复杂的Windows应用程序。

相关知识点

  1、熟悉Windows操作系统有关窗口和对话框的知识。

  2、熟悉Windows应用程序的基于事件的运行机制。

学习重点

  1、常用Windows窗体控件及其使用方法。

  2、对话框、菜单、工具栏等控件在Windows应用程序中的应用。

学习难点

  1、Windows窗体的设计和创建。

  2、各种窗体控件的综合应用。

  在Windows应用程序中,经常会接触到窗体,例如资源管理器、Word、Excel、记事本等许多应用程序都是由窗体组成的。Windows应用程序的产生使应用程序的设计更为简单,功能更加强大,使用更方便灵活。.NET Framework的一个优点就是提供了许多窗体控件,通过它们可以快速创建应用程序的用户界面。创建用户界面时,把控件从工具箱拖放到窗体上,把它们放在应用程序运行时需要的地方,再添加控件的事件处理程序,即可完成一个功能强大、界面美观的Windows应用程序。本章主要介绍一些最常用的Windows窗体控件。通过本章的学习,读者可以掌握Windows应用程序开发的基本流程和技巧,掌握常用控件的使用。

9.1 窗体与控件概述

  9.1.1 Windows窗体

  Windows窗体是C#用来建立Windows应用程序的出发点。不过,从窗体本身来看,它只是一个供用户操作计算机的界面而已。虽然用户可以直接在窗体上绘制对象和文本,但是窗体的真正作用是充当Windows控件的容器,而控件的本质就是窗体的成员对象,用于接收用户输入和输出处理结果。

  Windows窗体的基类是Form,位于System.Windows.Forms命名空间中。在第8章中已经介绍了Windows窗体的事件、事件方法,以及如何绑定事件方法与窗体。下面重点介绍Windows窗体的属性。

  表 9-1 列出了Windows窗体的主要属性。

表 9-1 窗体的主要属性
属性名称 说明
Name 窗体对象的名字,类似于变量的名字
BackColor 窗体的背景色
ControlBox 设置窗体是否有“控件”菜单框
Font 设置窗体控件中的文本的字体
ForeColor 窗体文本的前景色
FormBorderStyle 设置窗体的边框和标题栏的外观和行为
Icon 设置窗体的图标(要在窗体标题栏显示图标,需将ShowIcon属性设置为true)
MaximizeBox 设置窗体标题栏的右上角是否有最大化框
MinimizeBox 设置窗体标题栏的右上角是否有最小化框
ShowInTaskBar 是否在Windows系统的任务栏上显示窗体
StartPosition 窗体第一次出现时的位置
Text 窗体标题显示的文字
TopMost 设置窗体是否为最顶层的窗体。最顶层窗体始终显示子在桌面上的最高层,即使该窗体不是活动窗体或前台窗体
WindowState 窗体出现时最初的状态(正常、最大化、最小化)
   

  窗体和控件的属性可以在VS的“属性”窗口中进行设置,也可以通过编程来设置,如以下代码所示。

this.ShowInTaskbar = true;            //设置窗体出现在任务栏中
this.StartPosition = FormStartPosition.GenterScreen;        //设置窗体启动时位于屏幕正中央
this.Text="我的窗体";                        //设置窗体标题栏显示的文字
this.TopMost=true;                            //设置窗体为最顶端窗体
this.WindowState = FormWindowState.Maximized;            //设置窗体出现时的最初状态为最大化
this.FormBorderStyle =FormBorderStyle.Fixed3D;            //设置窗体的边框样式为固定的三维边框

  9.1.2窗体的控件

  1、.NET Framework中的窗体控件

  所谓控件就是控制计算机输入或输出操作的组件。在.NET Framework中,控件几乎都派生于System.Windows.Forms.Control类。窗体控件的使用方法有两种,即静态引用。其中,静态引用就是在设计窗体时直接把工具箱中的控件拖放到窗体设计区中。动态引用就是在源程序代码中通过控件类来创建控件对象,在完成属性设置后再将其添加到窗体之中。例如,实例1-2就展现了动态引用Label控件的编程方法。

  表9-2列出了一些常见的Windows控件。

常见的Windows控件
功能 控件/组件 说明
文本编辑 TextBox控件 文本框控件
  RichTextBox控件 增强的文本框,使文本能够以纯文本或RTF格式显示
信息显示(只读) Lable控件 标签,显示用户无法直接编辑的文本
  StatusStrip控件 状态条控制,显示应用程序的当前状态信息
  ProgressBar控件 向用户显示操作的当前进度
列表与选择 CheckBox控件 复选框,显示一个复选框和一个文本标签
  CheckedListBox控件 复选框列表,显示一组复选框和一个文本标签
  ComboBox控件 组合框,显示一个下拉式选项列表
  RadioButton控件 单选按钮,显示一个可打开或关闭的按钮
  ListBox控件 列表框,显示一个文本项和图形项(图标)列表
  ListView控件 列表视图,显示带图标的选项列表,用来创建类似于资源管理器右窗格的用户界面。其中,每个选项包括文本和图标
  NumericUpDown控件 增减按钮,显示用户可用向上和向下按钮滚动的数字列表
  TreeView控件 树型视图,用来创建类似于资源管理器左窗格的用户界面,其中每个选项又称为树的节点对象
  DomainUpDown控件 类似NumericUpDown,显示文本字符串选项列表,用户可单击向上和向下按钮选择其中一个选项
  TrackBar控件 追踪条,允许用户通过沿标尺移动的滑块来设置标尺上的值
图形显示 PictureBox控件 图像框,在一个框架中显示图形文件(如位图和图标)
  ImageList控件 用于存储图像列表,以便其他控件显示(如:PictureBox)
日期设置 DateTimePicker控件 显示一个图形日历以允许用户选择日期和时间
  MonthCalendar控件 显示一个图形日历以允许用户选择日期范围
对话框 ColorDialog控件 调色板,允许用户通过选择颜色设置界面元素的颜色
  FontDialog控件 字体对话框,允许用户设置字体及其属性
  OpenFileDialog控件 打开文件对话框,允许用户定位文件和选择文件
  PrintDialog控件 打印对话框,允许用户选择打印机完成打印并设置其属性
  PrintPreviewDialog控件 打印预览对话框,预览打印效果
  FolderBrowerDialog控件 文件夹浏览对话框,用来浏览、创建以及最终选择文件夹
  SaveFileDialog控件 保存文件对话框,允许用户保存文件
命令与菜单 Button控件 按钮,用来启动、停止或中断进程
  ToolStrip控件 创建工具栏
  MenuStrip控件 创建自定义菜单
  ContexMenuStrip控件 创建自定义上下文菜单
容器类控件 Panel控件 创建操作面板,集中管理窗体控件的显示或隐藏
  GroupBox控件 分组框,将窗体控件分组管理
  TabControl控件 选项卡,创建选项卡式的操作界面

  2、控件的属性

  每一个控件都有许多属性,用于处理控件的操作。表9-3列出了基类Control类的常见属性,大多数控件中都含有这些属性。

Control类常见的属性
BackColor 控件的背景色
Bottom 控件下边缘与其容器的工作区上边缘之间的距离(以像素为单位)
Enabled 控件是否可以对用户交互做出响应
ForeColor 控件的前景色
Height 控件的高度
Left 控件左边缘与其容器的工作区左边缘之间的距离(以像素为单位)
Location 控件的左上角相对于其容器的左上角的坐标
Name 控件的名称,可以在代码中用于引用该控件
Right 控件右边缘与其容器的工作区左边缘之间的距离(以像素为单位)
Size 控件的高度和宽度
TabIndex 控件的Tab键顺序
TabStop 指示用户能否使用Tab键将焦点放在该控件上
Text 与此控件关联的文本
Top 控件上边缘与其容器的工作区上边缘之间的距离(以像素为单位)
Visible 指示是否显示该控件
Width 控件的宽度
   

  本章通过设计一个个人理财软件对部分常见控件进行介绍。该系统将完成用户登录、收支情况管理和基本资料管理的界面设计,对数据库的连接和数据的管理将在第10章介绍。本系统的功能模块如图9-1所示。

9.2 按钮与文本显示、编辑控件

  9.2.1 按钮控件

  Button(按钮)控件是应用程序中使用最多的控件对象之一,常用来接收用户的鼠标操作,激发相应的事件,例如,让用户确认或者取消当前操作,通常要使用Button控件。按钮是用户与程序交互的最简便的方法。

  Button控件支持鼠标的单击和双击,也支持Enter键的操作。Button控件的使用比较简单,在设计时,先把Button控件添加到窗体设计区,然后双击它并编写Click事件代码,在运行程序时,单击该按钮就会执行Click事件中的代码。

  Button类最常用的属性有Name、Text、Visilbe、Enabled、FlatStyle、Image和ImageAlign等,在这里只介绍最常用的属性,其中,Name、Text、Visible和Enabled属性时大多数控件所共有的,在以下的控件中不再对这些属性进行介绍。

  1、Name属性

  Name属性用于设置对象的名称,设置按钮的Name属性时为了在代码中引用该按钮。

  当在窗体上添加一个Button控件时,系统默认其Name属性为button1,添加第二个按钮时,系统默认其Name属性为button2,以此类推,为了提高程序的可读性,将按钮与事件方法的功能很好地对应起来,建议最好给Button控件设置一个有实际意义的名称。

  2、Text属性

  Text属性的值就是以文本形式显示在按钮上的标题文字。

  为了方便用户操作,给按钮设置快捷键是很有必要的,例如当鼠标损坏时,用户可以按Alt+Y键来触发按钮操作。为此,在定义按钮的Text属性时,在快捷键字母的前面添加一个“&”字符。例如,若设置按钮的Text属性为“确定(&Y)”。

  有两种方法可以修改按钮的属性值:一种是在按钮控件的“属性”窗口中直接设置;另一种是用C#语句修改。后者的语法格式如下。

对象名.属性名=属性值
例如:
btnOk.Text="确定(&Y)"//设置“确定”按钮,显示为“确定(Y)”

  3、Visible属性

  Visible属性决定按钮是否可见,其值为true时可见,为false时隐藏。当一个控件不可见时,不能响应用户的鼠标和键盘操作,Visible属性在运行时生效。

   4、Enabled属性

  Enabled属性决定该按钮是否有效,其值为false时按钮文字以灰色显示,此时将不接受用户的键盘或鼠标操作。

  5、FlatStyle属性

  FlatStyle属性决定该按钮的样式,其值是FlatStyle枚举值。其中,FlatStyle有4个枚举值,分别为Flat(表示平面显示)、Popup(表示平面显示,但当鼠标指针移动到该控件时,外观为三维)、Standard(表示三维显示)、System(表示外观由操作系统决定)。Button控件的FlatStyle属性默认为Standard。

  图9-2显示了在4钟取值下按钮样式的外观。注意,当属性值为Popup时,鼠标指针移动到该控件与不在该控件上时按钮的样式是不一样的。

图 9-2 Button 控件的FlatStyle属性

  6、Image、ImageAlign、TextAign和TextImageRelation属性

  Image属性可以指定在按钮上显示一个图像,ImageAlign属性用来设置按钮上的图像的对齐方式,TextAlign用来获取或设置按钮上的文本的对齐方式,TextImageRelation用来获取或设置文本和图像的相对位置。如图 9-3所示,该按钮的ImageAlign属性值是它们分别表示图片在垂直方向上中间对齐、在水平方向上左边对齐,文本在垂直方向上中间对齐、在水平方向上居中对齐,在水平方向图像显示在文本的前方。

图 9-3 Button控件对图形和文本的显示

  Label(标签)控件是最常用的控件,主要用于在窗体上显示文本,也可以显示图片,显示文本时设置Text属性,显示图片时设置Image属性。Label的使用方法与Button相似,此处不再赘述。

  一般情况下,不需要为Label控件添加任何事件处理代码。Label的大多数属性派生于Control,除拥有前面介绍的一些属性外,常用的属性还有BorderStyle和AutoSize,这两个属性在前面章节中都使用过,其中AutoSize默认值为true,这将使Label控件根据字号和内容自动调整大小。

  BorderStyle属性决定控件边框的样式,该属性的值是BorderStyle枚举值。BorderStyle枚举型有三个枚举值,分别为None(无边框)、FixedSingle(单行边框)和Fixed3D(三维边框)。Label控件的BorderStyle属性默认为None。

  在.NET Framework中,除了标准的标签控件Label之外,还有LinkLabel控件。LinkLabel类似于Label,但以超链接方式显示文本。

9.2.3 文本编辑控件

  .NET Framework常用的文本编辑控件主要有:TextBox和Rich TextBox控件,它们都派生于TextBoxBase,而TextBoxBase派生于Control类。TextBoxBase提供了在文本框中处理文本的基本功能,例如选择文本、剪切、粘贴以及相关事件。

  1、Textbox控件

  TextBox控件的主要用途是让用户输入文本,用户可以在其中输入任何字符,最多可达32767个字符。用户输入的文本保存在Text属性中,在程序中引用Text属性即可获得用户输入的文本。

  当然,可通过编程来限定用户只能输入指定类型的字符(如只能输入数值)。默认情况下,TextBox是一个单行文本框,只能输入单行文本,当文本长度超过文本框长度时,超出部分自动隐藏,而不会自动换行显示。若要输入多行文本且让文本自动换行显示,则必须设置其中Multiple和WordWrap的属性值为True。

  TextBox控件的常见属性如表9-4所示。

表 9-4 TextBox 控件的常用属性
属性名称 说明
CausesValidation 指示是否启用Validating和Validated事件,以验证文本的有效性
CharacterCasing 用来指示是否将文本字符自动转换成大小写格式,其值为Lower表示将文本转换为小写;为Normal表示不进行任何转换;为Upper表示将文本转换为大写
MaxLength 用来指定在文本框中能输入或粘贴的最大字符数,默认值为32767
Multiline 是否显示多行文本,默认为false
PasswordChar 设置口令字符,当输入口令时不显示口令,而只显示口令字符
ReadOnly 指示文本框中的文本是否为只读,默认值为false
ScorllBars 在多行文本模式下,用来设置滚动条的显示方式
SelectedText 返回在文本框中当前选定的文本
SelectionLength 返回在文本框中选定的字符数
SelectionStart 返回在文本框中选定的文本的起始点
Text 当前已输入的文本
WordWrap 指示是否自动换行显示文本

  TextBox控件的常用事件如表 9-5所示。

 

  2、RichTextBox控件

  RichTextBox的功能与TextBox类似,但也有一些不同的地方,TextBox用来录入纯文本字符,而RichTexBox可用来显示和输入格式化的文本。RichTextBox使用富文本格式(Rich Text Format,RTF),可以显示字体、颜色和链接,从文件加载文本和加载嵌入的图像,以及查找指定的字符,因此RichTextBox常常称为增强的文本框。

  RichTextBox控件经常用来实现类似Microsoft Word的文本操作和显示功能。与TextBox控件相同的是,RichTextBox控件自带滚动条,但不同的是,RichTextBox控件拥有更多的滚动条设置。

  RichTextBox常见的属性见表9-6。

 

  从表9-6可以看出,大多数属性都与选中的文本有关,这时因为用户对RichTextBox控件中的文本应用的任何格式化操作都是对被选中的文本进行的。如果没有选中任何文本,格式化操作就从光标所在的位置开始应用,该位置称为插入点。

  9.2.4应用实例——用户登录

  【实例 9-1】设计一个简单的个人记账软件的用户登录界面,当输入正确的用户名和密码时,系统将给出正确的提示,否则给出错误提示。由于实际的身份验证需要与数据库建立连接,所以在这里先将功能简化,在第10 章介绍数据库相关知识时将进一步完善程序。

 

 源代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class 用户登录 : Form
    {
        public 用户登录()
        {
            InitializeComponent();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            string userName = txtName.Text;
            string password = txtPwd.Text;
            if (userName == "admin" && password == "555")
            {
                MessageBox.Show("欢迎进入个人理财系统!", "登录成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("您输入的用户名或密码错误!", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            txtName.Text = "";
            txtPwd.Text = "";
            txtName.Focus();
        }
    }
}
View Code

运行成功效果图:

 

9.3 列表与选择控件

  列表与选择控件用于在一组可选项中选择一个或多个选项,常见的选择控件包括单选按钮、复选框、列表框和组合框等。

 

   9.3.1 RadioButton控件

  若干个RadioButton(单选按钮)控件组成多个互斥的选项列表,用户只能从中选择一个选项。RadioButton控件样式如“”所示。

  除了Name、Text、Image、Enable和Visible外,RadioButton的其他常用属性见表9-8.

 

 

  RadioButton控件的常用事件如表9-9所示。

 

 

  单选按钮都有两种工作状态:未选中和选中。因为它的Checked属性默认为false,故默认为未选中。单选按钮在首次被击中时,Checked属性被自动修改为true,由未选中变成选中状态,同时触发CheckChanged事件。单选按钮一旦被选中,如何无论连续单击它多少次,其Checked属性不会再次被修改,也不会再次触发CheckChanged事件。

  与CheckChanged事件不同的是,Click事件与单选按钮是否选中的状态无关,只要用户单击鼠标就会触发Click事件。另外,当单选按钮的AutoCheck属性为false时,该按钮自动功能失效,不会被选中,此时只会触发Click事件,不会触发CheckChanged事件。

 

   9.3.2 CheckBox控件

  若干个CheckBox(复选框)控件组成多个选项列表,用户可根据需要从中选择一项或多项。一个选项被选中的效果如“”所示。CheckBox和RadioButton控件的功能相似,允许用户从选项列表中进行选择,但主要区别是,RadioButton控件只允许用户从互相排斥的选项中选择一个,CheckBox控件允许用户选择多个选项。CheckBox的属性和事件与RadioButton非常类似,但有两个新属性,见表9-10。

 

 

  与RadioButton一样,CheckBox也有CheckChanged事件,但其功能稍有区别。CheckBox控件的常用事件如表9-11所示。

 

 

 

  9.3.3 ListBox控件

 

  ListBox(列表框)控件用于显示一组字符串,可以从中选择一个或多个选项。与复选框和单选按钮一样,列表框也提供了要求用户选择一个或多个选项的方式。

 

  ListBox控件的常用属性见表9-12。

 

 

 

  ListBox控件的常用方法见表9-13。

 

 

  ListBox控件的常用事件主要是:SelectedIndexChanged,表示选中项的索引被改变时触发的事件。

  9.3.4 ComboBox控件

  ComboBox(组合框)控件把文本框控件和列表框组合在一起,使用户可以从列表中选择选项,也可以直接输入文本。ComboBox的默认行为是显示一个可编辑文本框,该文本框具有一个隐藏的下拉列表。其DropDownStyle属性指定组合框的样式,其值为Simple时,表示简单的下拉列表,即始终显示下拉列表框;为DropDownList时,表示文本部分不可编辑,必须从下拉列表中选择;为DropDown时,表示默认下拉列表框,既可以直接编辑文本部分,也可以从下拉列表中选择。

  9.3.5 其他常用控件

  除上述选项类控件外,还有一些与列表选择有关的控件。

  (1)CheckedListBox:复选框列表控件,用来显示一个可滚动的选项列表,每个选项的左边都有一个复选框。

  (2)DomainUpDown:该控件由一个文本框和一对用于在列表中上下移动的箭头组合而成。该控件用来构造由若干文本组成的列表。用户可以单击向上和向下按钮在列表中移动,或者按向上和向下键,或者输入与列表项匹配的字符串等多种方法选择某个选项。

  (3)NumericUpDown:增减按钮,该控件由一个文本框与一对箭头组合而成,效果如“”所示。该控件用来构造数字选项列表。用户可以通过单击向上和向下按钮,或者按向上键和向下键,或者输入一个数字来增大和减小数字。该控件的Minimun和Maximum属性指定列表中数字的最小值和最大值,DecimalPlaces属性指定小数位数。

  (4)ListView:列表视图,该控件显示带图标的选项列表,使用该控件可以创建类似于Windows资源管理器右窗格的用户界面。该控件具有5钟视图模式:LargeIcon、SmallIcon、List、Title和Details。

  (5)TreeView:树形视图,该控件为用户显示树形的选项结构,用来创建类似于资源管理器左窗格的用户界面,在树形视图中一个节点(称为“父节点”)可以包含其他节点(称为“字节点”),用户可以展开或折叠显示父节点。该控件的CheckBoxes属性决定是否在每个节点旁边显示一个复选框(为true时才显示);每个节点的Checked属性指示是否选中该节点,为true时表示选中。

  (6)DateTimePicker:显示一个图形日历以允许用户选择日期或时间。

  (7)MonthCalendar:显示一个图形日历以允许用户选择日期范围。

  9.3.6 应用实例————添加个人收支明细

  【实例 9-2】在项目MyAccounting中添加一个窗体,实现如图9-7所示的效果,用于添加个人收支明细。

 

  运行效果如下:

  源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyAccounting
{
    public partial class AddExpenditure : Form
    {
        public AddExpenditure()
        {
            InitializeComponent();
        }


        private void radioExpenditure_CheckedChanged(object sender, EventArgs e)
        {
            cboCategory.Items.Clear();              //清空组合框中所有项
            if(radioExpenditure.Checked==true)
            {
                cboCategory.Items.Add("生活消费");  //添加支出项
                cboCategory.Items.Add("固定资产");
                cboCategory.Items.Add("休闲娱乐");
                cboCategory.Items.Add("医疗药品");
                cboCategory.Items.Add("教育培训");
                cboCategory.Items.Add("其他支出");
            }
            else
            {
                cboCategory.Items.Add("工作收入");  //添加收入项
                cboCategory.Items.Add("投资收益");
                cboCategory.Items.Add("其他收入");
            }
            cboCategory.SelectedIndex = 0;          //初始选择组合框中的第一项
        }
        //根据组合框中选择的不同收支类别,向列表框中加载该收支类别的收支项
        private void cboCategory_SelectedIndexChanged(object sender, EventArgs e)
        {
            lstItem.Items.Clear();              //清除列表框中所有项
            switch(cboCategory.Text.ToString())
            {
                case "生活消费":
                    lstItem.Items.Add("餐饮");
                    lstItem.Items.Add("生活用品");
                    lstItem.Items.Add("交通费");
                    lstItem.Items.Add("水电费");
                    //......下略,可以自行添加适当项目
                    break;
                case "固定资产":
                    lstItem.Items.Add("服装");
                    lstItem.Items.Add("家用电器");
                    //......下略,可以自行添加适当项目
                    break;
                case "医疗药品":
                    lstItem.Items.Add("药品");
                    lstItem.Items.Add("住院");
                    //......下略,可以自行添加适当项目
                    break;
                case "休闲娱乐":
                    lstItem.Items.Add("旅游");
                    lstItem.Items.Add("休闲项目");
                    //......下略,可以自行添加适当项目
                    break;
                case "教育培训":
                    lstItem.Items.Add("报名费");
                    lstItem.Items.Add("培训费");
                    lstItem.Items.Add("考试费");
                    lstItem.Items.Add("书本费");
                    lstItem.Items.Add("学习视频会员费");
                    //......下略,可以自行添加适当项目
                    break;
                case "工作收入":
                    lstItem.Items.Add("工资");
                    lstItem.Items.Add("出差补贴");
                    lstItem.Items.Add("奖金");
                    //......下略,可以自行添加适当项目
                    break;
                case "投资收益":
                    lstItem.Items.Add("存款利息");
                    lstItem.Items.Add("理财");
                    lstItem.Items.Add("基金");
                    lstItem.Items.Add("股票");
                    //......下略,可以自行添加适当项目
                    break;
                default:
                    lstItem.Items.Add("");
                    break;
            }
            lstItem.SelectedIndex = 0;              //初始选择列表框中的第一项
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            rtxtRemarks.Clear();
            rtxtRemarks.AppendText("要保存的信息为:\n");
            rtxtRemarks.AppendText(cboCategory.Text.ToString());
            rtxtRemarks.AppendText("-");
            rtxtRemarks.AppendText(lstItem.Text.ToString());
            rtxtRemarks.AppendText("\n 日期:");
            rtxtRemarks.AppendText(dtpDate.Value.ToLongDateString());
            rtxtRemarks.AppendText("\n 说明:");
            rtxtRemarks.AppendText(txtExplain.Text);
            rtxtRemarks.AppendText("\n 收支人:");
            if (checkBox1.Checked) rtxtRemarks.AppendText(checkBox1.Text);
            if (checkBox2.Checked) rtxtRemarks.AppendText(""+checkBox2.Text);
            if (checkBox3.Checked) rtxtRemarks.AppendText(""+checkBox3.Text);
            if (checkBox4.Checked) rtxtRemarks.AppendText(""+checkBox4.Text);
            if (checkBox5.Checked) rtxtRemarks.AppendText(""+checkBox5.Text);
            if (checkBox6.Checked) rtxtRemarks.AppendText(""+checkBox6.Text);
            rtxtRemarks.AppendText("\n 金额:");
            rtxtRemarks.AppendText(numAmount.Value.ToString());
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();               //关闭当前窗体
        }
    }
}
View Code

  9.4 图形显示控件

  在Windows应用程序设计时,经常需要显示图像,以增强程序的显示效果。常见的图像显示控件为PictureBox和ImageList控件。

  9.4.1 PictureBox控件

  PictureBox控件用于显示位图、GIF、JPEG、图元文件或图标格式的图形,所显示的图片由Image属性确定,该属性可在运行时或设计时设置。该控件的SizeMode属性控制图像在图片框中的显示位置和大小,其属性值为PictureBoxSizeMode枚举值,当其属性值为Normal(默认值)时,图像置于图片框的左上角,凡是因尺寸过大而不合适图片框的部分都将被裁掉;为StretchImage时,图像将被拉伸,以便适合图片框的大小;为AutoSize时,图片框的大小将被自动调整,以适合图像的大小;为CenterImage时,图像位于图片框的中心。

  9.4.2 ImageList控件

  ImageList控件本身并不显示图像,只用于存储图像,可以将位图、图标添加到ImageList中,这些图像随后可由其他控件显示。ImageList控件可以存储一系列的图像集合。只需更改某个控件的ImageIndex或ImageKey属性,就可以改变该控件显示的图像。还可以显示同一个文件列表,则当更改图像列表中某个文件的图标时,新图标将同时显示在两个视图中。

  若要使ImageList控件与一个控件关联,需要将该控件的ImageList属性设置为ImageList控件的名称。ImageList控件的主要属性是Images,它包含一个图像集合。集合所使用的颜色数量。所有图像都将以同样的大小显示,该大小由ImageSize属性设置。较大的图像将缩小至适当的尺寸。

  9.4.3 应用实例——关于我们

  效果图如下:

 

 

  源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyAccounting
{
    public partial class About : Form
    {
        public About()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Close();               //关闭”关于我们“窗体
        }
    }
}
View Code

 

  9.5  容器控件

  日常生活中的容器是用来盛放东西的,例如,杯子或瓶子都属于容器,可以用来装水,也可用来装油。容器控件类似于一般的容器,是一种特殊的控件,主要用来存放其他控件。把一组像Label、Text Box、和Button之类的控件放到容器控件之中,通过程序来设置容器控件的属性,这样就可以一次更改这一组控件的可见性。

  常见的容器控件有GroupBox、Panel、Splitter和TabControl。

  9.5.1 GroupBox控件

  GroupBox(分组框)控件用于为其他控件提供可识别的分组。利用分组框把窗体按功能划分为几个操作区域,每个区域由分组框提供统一操作提示,这样有利于用户操作。使用GroupBox控件不但能把一个窗体的各种功能进一步分类,而且还可实现所包含的一组控件的集体隐藏或移动。也就是说,当隐藏或移动单个GroupBox控件时,它包含的所有控件也会一起隐藏或移动。

  在窗体上创建GroupBox控件及其内部控件时,必须先建立GroupBox控件,然后在其内添加各种控件。如果要将窗体上已经放好的控件进行分组,则应选中控件,然后将它们剪切并粘贴到GroupBox控件中,或者直接把控件拖放到GroupBox之中。

  9.5.2 Panel控件

  Panel(面板)控件类似于GroupBox控件,二者存在的区别是:GroupBox控件能显示标题文本,但不能显示滚动条,Panel控件与之相反,无标题文本,但可以显示滚动条。设置Panel控件的AutoScroll属性为true,即可显示滚动条。从显示效果来看,Panel和GroupBox控件都允许自定义面板的外观,包括BackColor、BackGroundImage、BorderStyle、ForeColor和Font等属性。

  9.5.3 TabControl控件

  TabControl(选项卡)控件用于显示多个选项卡,这些选项卡类似于档案柜中文件夹中的标签。选项卡中可包含图片和其他控件。选项卡控件通常用来创建多页对话框,这种对话框在Windows系统中大量存在,例如,Windows任务管理器就是由多个选项卡组成的对话框。此外,TabControl控件还可以用来创建“属性”窗口,用来设置对象的相关属性。

  TabControl控件的最重要的属性是TabPages,该属性称为选项卡项对象集,由若干个TabPage对象组成。每一个选项卡提供Click事件,当单击选项卡标签时,将触发该事件。

表 9-16 TabControl控件的属性
属性名称 说  明
Alignment 控制选项卡在TabControl控件中的显示位置,默认为顶部位置
Appearance 控制选项卡的显示方式
HotTrack 热点追踪,当属性值=true时,鼠标指针一量移过某个选项卡,其外观就会改变
RowCount 返回当前显示的选项卡行数
SelectdItem 返回或设置当前选定的选项卡的索引
SelectedTab 返回或设置当前选定的选项卡
TabCount 返回选项卡的个数
TabPages

选项卡集合,使用这个集合可以添加和删除TabPage对象

  9.5.4 应用实例——添加收支项目

  效果图如下:

  源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyAccounting
{
    public partial class AddItems : Form
    {
        public AddItems()
        {
            InitializeComponent();
        }

        private void rdoExpenditure_CheckedChanged(object sender, EventArgs e)
        {
            cboCategory.Items.Clear();              //清除组合框中所有项
            cboCategory.Items.Add("一级大类");      //可以添加一类类别
            if (rdoExpenditure.Checked == true)
            {
                cboCategory.Items.Add("生活消费");      //添加支出项
                cboCategory.Items.Add("固定资产");
                cboCategory.Items.Add("休闲娱乐");
                cboCategory.Items.Add("医疗药品");
                cboCategory.Items.Add("教育培训");
                cboCategory.Items.Add("其他支出");
            }
            else
            {
                cboCategory.Items.Add("工作收入");      //添加收入项
                cboCategory.Items.Add("投资收益");
                cboCategory.Items.Add("其他收入");
            }
            cboCategory.SelectedIndex = 0;              //初始选择组合框中的第一项
        }

        private void btnPreview_Click(object sender, EventArgs e)
        {
            //如果没有填写收支项目名称,则弹出对话框告知用户
            if (txtName.Text.Trim() == string.Empty)
            {
                MessageBox.Show("请填写收支项目名称!", "信息不完整", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            else
                tabControl1.SelectedTab = tabPage2;             //进入"确认信息"选项卡
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 1)
            {
                if(txtName.Text.Trim()==string.Empty)
                {
                    MessageBox.Show("请填写收支项目名称!", "信息不完整", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    rtxMsg.Clear();
                    rtxMsg.AppendText("要添加的收支项目为:");
                    rtxMsg.AppendText(txtName.Text);
                    rtxMsg.AppendText("\n所属类别:" + cboCategory.SelectedItem.ToString());
                    if (rdoExpenditure.Checked == true) rtxMsg.AppendText("\n是支出类型的项目");
                    else rtxMsg.AppendText("\n是收入类型的项目");
                }
            }
        }
    }
}
View Code

  9.6 对话框

  9.6.1 对话框概述

  Windows系统一共有两种对话框:模态对话框、非模态对话框。

  1、模态对话框

  所谓的模态对话框,就是指该对话框弹出的时候,鼠标不能单击该对话框之外的区域。模态对话框往往是用户执行了某种特殊操作后才显示的。例如,Word的“字数统计”

对话框就是一个模态对话框。

  对话框实际上是一种特殊的窗体,从代码上看,对话框其实也是一个类,这个类是从窗体的类继承下来的。要打开一个模态对话框,可以使用窗体的ShowDialog()方法,一般的形式如下:

  窗体对象.ShowDialog();

  【实例 9-5】创建一个新Windows应用程序,打开一个模态对话框。

  效果图如下:

 

 

   2、非模态对话框

  非模态对话框通常用于显示用户需要经常访问的控件和数据,并且在使用这个对话框的过程中需要访问其他窗体的情况,例如,Word的“查找和替换”对话框,就是一个非模态对话框。

  创建非模态对话框和模态对话框相似,模态对话框使用ShowDIalog方法显示,而非模态对话框使用Show方法显示。

  在设计模式下,双击“打开非模态对话框”按钮,进行如下代码的编辑。

 private void btnShow_Click(object sender, EventArgs e)
        {
            ModelForm dlg = new ModelForm("这是一个非模态对话框");
            dlg.Show();
        }

程序源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class 实例9_5 : Form
    {
        public 实例9_5()
        {
            InitializeComponent();
        }

        private void btnShowDialog_Click(object sender, EventArgs e)
        {
            ModelForm dlg = new ModelForm("这是一个模态对话框");         //构建ModelForm的实例,并传值
            dlg.ShowDialog();                               //打开模态对话框
        }

        private void btnShow_Click(object sender, EventArgs e)
        {
            ModelForm dlg = new ModelForm("这是一个非模态对话框");
            dlg.Show();
        }
    }
}




//以下代码为另一窗体代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class ModelForm : Form
    {
        private string message; //ModelForm的私有成员
        public ModelForm(string msg)        //实例化ModelForm的对象时,传入参数为message初始化
        {
            InitializeComponent();
            message = msg;
        }

        private void ModelForm_Load(object sender, EventArgs e)
        {
            label1.Text = message;          //将message的值显示出来
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
View Code

  9.6.2消息框

  消息框用来显示系统消息,它是一种特殊的对话框,通常由消息文本、图标和一个或多个按钮组成。如图9-16所示为Word中弹出的消息框。

  

 

 

  在.NET中,可以使用MessageBox产生消息框。与其他对话框或窗体不同,不需要创建MessageBox类的实例,调用其静态方法成员Show就可以显示消息框。在前面的一些实例中已经用到了MessageBox.Show()方法,这里对该方法进行详细说明。

  MessageBox.Show方法有21种重载格式,其中较为常用的重载格式如表9-18所示。

 

 

   1、消息框按钮

  除了默认的“确定”按钮外,消息框上还可以放置其他按钮。这些按钮可以收集用户对消息框中问题的响应,一个消息框中最多可显示三个按钮,但不能随意定义这些按钮,必须从MessageBoxButtons枚举的预定义按钮组中选择,如表9-19所示

 

 

   单击消息框中的某一个按钮时,Show方法将返回一个DialogResult枚举值指示用户之前所做的操作。表9-20显示了DialogResult的枚举成员。

 

 

 例如,以下代码:

DialogResult result = MessageBox.Show("这是一个示例","示例",MessageBoxButtons.AbortRetryIgnore,MessageBoxIcon.Information);
if(result ==DialogResult.Ignore)
{
  //当用户单击了“忽略”按钮后执行的方法  
}

  以上代码展示了如何利用MessageBoxButtons枚举值来判断用户是否在消息框中单击了”忽略“按钮。

 

   2、消息框图标

  MessageBoxIcon枚举用于指定消息框中显示什么图标。尽管可供选择的图标只有4个,但是在MessageBoxIcon枚举中共有9个成员,如表9-21所示。

 

 

 上面的代码执行后,弹出的消息框如图9-17所示。

 

 

   9.6.3 通用对话框

  .NET平台提供了一组基于Windows的标准对话框界面,包括OpenFileDialog(文件打开)、SaveFileDialog(文件另存为)、FolderBrowerDialog(文件夹选择)、ColorDialog(颜色)以及FontDialog(字体)对话框等。其中,OpenFileDialog用于打开一个或多个文件,而SaveFileDialog用于保存文件时指定一个文件名和路径,FolderBrowerDialof用于选择一个文件夹,这三个对话框的使用方法将在第11章进行详细介绍。

  通用对话框常用于从用户处获取一些信息如输入文件名。通用对话框是Windows操作系统的一部分,它们具有一些相同的方法和事件,如表9-22所示。

 

 

下面的代码演示了如何使用字体对话框。

FontDialog fontDialog1=new FontDialog();
if(fontDialog1.ShowDialog()==DialogResult.OK)
{
    richTextBox1.Font=fontDialog.Font;
}

 

  以上代码首先创建一个FontDialog对话框类的新实例fontDialog1,接着调用其ShowDialog()方法,以显示该对话框,等待并响应用户的操作。当用户单击”确定“按钮后,用户的操作状态被返回,通过对话框的属性即可获取用户输入的值。在本例中,把fontDialog1对象的Font属性赋值给richTextBox1的Font属性,从而更改文本的字体。

  下面重点介绍ColorDialog和FontDialog对话框。

  1、ColorDialog

  ColorDialog对话框允许用户从调色板中选择颜色以及将自定义颜色添加到该调色板。此对话框与Windows的应用程序中看到的用于选择颜色的对话框相同,如图9-18所示。

 

   ColorDialog对话框常用的属性如表9-23所示。

 

   2、FontDialog

 

 

  FontDialog对话框用于列出所有已安装的Windows字体、样式和字号,以及各字体的预览效果。用户可以通过”字体“对话框来改变文字的字体、样式、字号和颜色。”字体“对话框如图9-19所示。

  FontDialog对话框常用的属性如表9-24所示。

 

   9.6.4 应用实例————简单的文本编辑器

  效果图如下:

  源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class 实例9_7 : Form
    {
        public 实例9_7()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            colorDialog1.Color = richTextBox1.ForeColor;        //创建颜色对话框实例
            //弹出对话框,并判断用户是否单击了”确定“按钮
            if(colorDialog1.ShowDialog()==DialogResult.OK)
            {
                richTextBox1.ForeColor = colorDialog1.Color;        //设置文本框的字体颜色
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            fontDialog1.Font = richTextBox1.Font;                   //创建字体对话框实例
            //弹出对话框,并判断用户是否单击了”确定“按钮
            if (fontDialog1.ShowDialog() == DialogResult.OK)
            {
                richTextBox1.Font = fontDialog1.Font;               //设置文本框的字体
            }
        }
    }
}
View Code

  9.7 菜单、工具栏和状态栏

  菜单、工具栏和状态栏是Windows应用程序中常见的部分,在VS中,可以使用可视化的方式快速创建菜单。

 

  9.7.1 菜单

  在Windows应用程序中,菜单是常用的用户界面。除了基于对话框的简单应用程序外,实际上大部分Windows应用程序都提供一个用于用户和应用程序进行交互的下拉菜单,出现在应用程序界面上方边缘的菜单,通常称为应用程序的主菜单或菜单栏。而右击一个控件时出现的菜单通常称为快捷菜单,有时也称为上下文菜单。

  1、下拉菜单

  在工具箱中直接双击MenuStrip(下拉菜单)控件,即可在窗体的顶部建立一个菜单,此时窗体的底部还显示出创建的菜单名称。把鼠标移到”请在此处键入“处,将会显示一个三角形按钮,单击该按钮将弹出一个下拉列表,其中包括MenuItem、ComboBox和TextBox共三个选项,刚创建好的菜单默认为MenuItem,如图9-21所示

  在”请在此处键入“处单击,即可在该文本框中输入文本,即设置菜单项的标题内容,如图9-22所示。输入内容后,在该文本的下方和右侧均会出现类似的”请在此处键入“字样,此时,可在下方为当前菜单创建子菜单,在右侧可以创建同一级别的其他菜单。

  在输入标题内容时,可以在标题内容的某个字母前加”&“,这样该字母将成为快捷键。例如,”文件(&F)“将具有一个快捷键Alt+F,程序运行时按Alt+F键同样可以选择此菜单命令。

  如果将菜单标题(即菜单命令的Text属性)设置为”-“(减号),则此菜单项将显示为分隔符,如图9-23所示的”保存“和”关闭“命令之间就有一个分隔符。

 

 

 

  2.上下文菜单

  

 

   9.7.2 工具栏

       

  

 

   9.7.3 状态栏

 

      

  

 

   9.7.4 应用实例——个人理财系统主窗口设计

 

 

 

   9.8 SDI和MDI应用程序

  

 

       

 

      

       

 

   【课后实例】

  一、字体设置

  效果图如下:

  源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class 字体设置 : Form
    {
        Font font;
        public 字体设置()
        {
            InitializeComponent();
        }

        private void 字体设置_Load(object sender, EventArgs e)
        {
            comboBox1.Items.Clear();
            for(int i = 5; i <= 72; i++)
            {
                comboBox1.Items.Add(i);
            }
            font = richTextBox1.Font;                   //获取当前字体设置
            comboBox1.Text = font.Size.ToString();      //获取文本框当前的字体大小
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            FontStyle fontStyle1, fontStyle2, fontStyle3, fontStyle4;
            fontStyle1 = FontStyle.Regular;
            fontStyle2 = FontStyle.Regular;
            fontStyle3 = FontStyle.Regular;
            fontStyle4 = FontStyle.Regular;
            if (checkBox1.Checked)
            {
                fontStyle1 = FontStyle.Bold;
            }
            if (checkBox2.Checked)
            {
                fontStyle2 = FontStyle.Italic;
            }
            if (checkBox3.Checked)
            {
                fontStyle3 = FontStyle.Underline;
            }
            if (checkBox4.Checked)
            {
                fontStyle4 = FontStyle.Strikeout;
            }
            //初始化新Font,它使用指定的现有Font和FontStyle枚举
            font = new Font(font, fontStyle1 | fontStyle2 | fontStyle3 | fontStyle4);
            richTextBox1.Font = font;
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            string fontFamily = font.FontFamily.Name;
            if (radioButton1.Checked) fontFamily = radioButton1.Text;
            else if (radioButton2.Checked) fontFamily = radioButton2.Text;
            else if (radioButton3.Checked) fontFamily = radioButton3.Text;
            else fontFamily = radioButton4.Text;
            font = new Font(fontFamily, font.Size, font.Style);
            richTextBox1.Font = font;
        }

        private void radioButton5_CheckedChanged(object sender, EventArgs e)
        {
            Color color = richTextBox1.ForeColor;
            if (radioButton5.Checked) color = Color.Red;
            else if (radioButton6.Checked) color = Color.Green;
            else if (radioButton7.Checked) color = Color.Blue;
            else color = Color.Black;
            richTextBox1.ForeColor = color;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            float size = Convert.ToSingle(comboBox1.Text);
            font = new Font(font.FontFamily, size);
            richTextBox1.Font = font;
        }
    }
}
View Code

  二、通讯录管理软件

  效果图如下:

  源代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class 通讯录管理 : Form
    {
        public 通讯录管理()
        {
            InitializeComponent();
        }

        private void 新建联系人NCtrNToolStripMenuItem_Click(object sender, EventArgs e)
        {
            新建联系人 newConFrm = new 新建联系人();      //创建子窗体对象
            newConFrm.MdiParent = this;                     //指定当前窗体为MDI父窗体
            newConFrm.Show();                               //打开子窗体
            toolStripLabel1.Text = "新建联系人";
        }
    }
}


//以下代码为另一个窗体
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 第九章
{
    public partial class 新建联系人 : Form
    {
        public 新建联系人()
        {
            InitializeComponent();
        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
View Code