在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → Visual C#.NET程序设计教程 习题参考答案

Visual C#.NET程序设计教程 习题参考答案

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:1.51M
  • 下载次数:58
  • 浏览次数:9553
  • 发布时间:2019-01-10
  • 实例类别:C#语言基础
  • 发 布 人:小七鸭
  • 文件格式:.doc
  • 所需积分:2
 相关标签:

同类人气实例

实例介绍

【实例简介】

【实例截图】


from clipboard

from clipboard

【核心代码】

第1部分 Visual C#.NET程序设计教程
习题参考答案
第1章 概述
1.选择题
(1)公共语言运行库即__________。
     A. CRL         B. CLR             C. CRR         D. CLS
(2).NET平台是一个新的开发框架,__________是.NET的核心部分。
     A. C#          B. .NET Framework   C. VB.NET      D. 操作系统
(3)项目文件的扩展名是__________。
     A. csproj        B. cs               C. sln           D. suo
(4)利用C#开发应用程序,通常有3种类型,不包括__________。
     A. 控制台程序   B. Web应用程序     C. SQL程序     D. Windows程序
(5)运行C#程序可以通过按键__________实现。
     A. F5           B. Alt F5           C. Ctrl F5       D. Alt Ctrl F5 
答案【B】【B】【A】【C】【A】
2.思考题
(1)简述面向对象程序设计的特点。
答:面向对象程序设计方法把对象作为数据和操作的组合结构,用对象分解取代了传统方法的功能分解,把所有对象都划分为类,把若干个相关的类组织成具有层次结构的系统,即下层的子类继承上层的父类所具有的数据和操作,而对象之间通过发送消息相互联系。
面向对象的程序设计大多采用可视化的方式,通过类、对象、封装、继承、多态等机制形成一个完善的编程体系。
(2)简述类和对象的关系。
答:类是对象的抽象,不能进行直接的操作。对象是类的实例,对象可以通过事件驱动实现程序的运行。对象的属性、事件和方法来自类的继承,可以自己进行修改和调用。
(3)简述面向对象的基本特征。
答:面向对象有3个基本特征,即封装、继承和多态。
① 封装性,即把具有一致的数据结构(属性)和行为(操作)的对象封装成抽象的类。
② 继承性,是子类自动共享父类数据结构和方法的机制,它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
③ 多态性,是指相同的操作或函数可作用于多种类型的对象上并获得不同的结果。
(4)说明Visual C#.NET和Visual Studio.NET的关系。
答:Visual Studio.NET是微软提供的一套完整的应用程序开发工具集,在这个工具集中可以用Visual C#、Visual C  、Visual Basic.NET等语言进行开发,而Visual C#.NET是.NET平台上最主要的开发语言之一。
(5)简述创建Windows应用程序的步骤。
答:创建Windows应用程序的步骤如下:
① 选择“开始|程序|Microsoft Visual Studio 2008|Microsoft Visual Studio 2008”命令,启动Visual Studio 2008开发环境。
② 通过“起始页|最近的项目|创建”命令,或者“文件|新建”命令打开“新建项目”对话框。
③ 在“新建项目”对话框中,选择“Visual C#”项目类型和“Windows窗体应用程序”模板,然后可以对所要创建的项目进行命名、选择保存文件的位置、是否创建解决方案目录的设置,也可以对项目所在的解决方案命名。
④ 单击“确定”按钮,完成项目的创建,进入Windows窗体设计器。
3.上机练习题
(1)创建一个控制台程序,输出字符串“C#.NET程序设计”。
答:具体步骤如下:
① 选择“开始|程序|Microsoft Visual Studio 2008|Microsoft Visual Studio 2008”命令,启动Visual Studio 2008。
② 选择“文件|新建|项目”命令,启动后选择Visual C#开发项目类型,出现“新建项目”对话框。
③ 选择“控制台应用程序”,输入项目名称exerciseConsole,选择项目文件存放位置,单击“确定”按钮,进入编程界面。
④ 在代码窗口中找到Main方法输入相应代码,Program.cs文件的所有代码如下所示:
using System;
namespace exerciseConsole
{
    class Program
    {
        static void Main(string[] args)
        {   
            Console.WriteLine("C#.NET程序设计");  
     		Console.ReadLine();
        }
    }
}
⑤ 单击工具栏上的“启动调试”按钮或按F5键运行程序。
(2)创建一个Windows应用程序,在窗体中输出字符串“After all, it still flows east.”。
答:具体步骤如下:
① 启动Visual Studio 2008。选择“文件|新建|项目”命令,启动后选择Visual C#开发项目类型,出现“新建项目”对话框。
② 选择“Windows窗体应用程序”,输入项目名称exerciseWindows,选择项目文件存放位置,单击“确定”按钮,进入到项目的设计界面。
③ 在工具箱中双击Label控件,Form1中会生成一个标签对象label1,单击label1,在“属性”窗口中将其Text属性修改为“After all, it still flows east.”,如图1.1所示。

图1.1  Windows窗体应用程序设计界面
④ 双击Form1窗体的空白位置,切换到代码窗口,同时为Form1添加Load事件处理程序。在Form1_Load中添加代码如下:
private void Form1_Load(object sender, EventArgs e)
{
//设置窗体标题栏显示的文本
         this.Text = "Windows窗体应用程序";
}
⑤ 单击“启动调试”按钮或按F5键运行程序。
(3)创建一个Web应用程序,在窗体中输出字符串“ASP.NET Web窗体”。
答:具体步骤如下:
① 启动Visual Studio 2008。
② 选择“文件|新建|网站”命令,打开“新建网站”对话框。
③ 选择“ASP.NET网站”模板,输入网站文件系统的文件夹名称(如D:\1\exerciseWebSite),选择Visual C#语言,单击“确定”按钮,进入到Web窗体的编辑视图。
④ 在解决方案管理器中右击Default.aspx,在弹出的快捷菜单中选择“重命名”命令,将Default.aspx修改为exerciseWeb.aspx, 同时系统将Default.aspx.cs修改为exerciseWeb. aspx.cs。
⑤ 单击VS 2008设计区左下角的“设计”选项卡,切换到设计界面,在工具箱中双击Label控件,会生成一个标签对象Label1,在“属性”窗口中将其Text属性修改为“ASP.NET Web窗体”,如图1.2所示。

图1.2  Web窗体应用程序设计界面
⑥ 右击Visual Studio 2008的设计区,选择“查看代码”命令,将Web窗体的编辑视图切换为源程序代码文件exerciseWeb.aspx.cs的编辑视图,在Page_Load中添加代码如下:
protected void Page_Load(object sender, EventArgs e)
{
        //设置网页标题栏显示的文本
        this.Title = "Web窗体应用程序";
}
⑦ 单击“启动调试”按钮或按F5键运行程序。
第2章 Visual C#.NET语法基础
1.选择题
(1)下列标识符不合法的是__________。
    A. abc          B. abc123          C. abc-1         D. a3b
(2)转义字符不可以表示__________。
    A. 任何字符     B. 字符串         C. 字母          D. 小数点
(3)表达式5/2 5%2-1的值是__________。
    A. 4            B. 2              C. 3.5            D. 2.5
(4)下列数值类型的数据精度最高的是__________。
    A. int           B. flaot           C. decimal        D. ulong
(5)常用集合类不包括__________。
    A. 数组         B. 结构           C. 列表           D. 字典
答案【C】【B】【B】【C】【B】
2.思考题
(1)说明C#值类型与引用类型数据的区别。
答:从数据存储的角度,C#的类型可分为值类型和引用类型。值类型用于存储数据的值,而引用类型用于存储对实际数据的引用。C#的值类型可以进一步划分为简单类型(包括整型、实数型、字符型和布尔型)、枚举类型和结构类型,而引用类型包括类、接口、委托、数组和字符串等。值类型数据存储于栈内存中;而引用类型的数据存储于堆内存中,在栈内存中存放定位到存储具体值的索引位置编号。
(2)简述枚举型、结构型、数组和委托4种数据类型的区别。
答:枚举和结构数据类型是值类型,而数组和委托数据类型是引用类型。
① 枚举实际上是为一组在逻辑上密不可分的整数值提供便于记忆的符号,是一些取了名字的常量集合,C#使用enum来定义一个枚举类型。
② 结构类型是一种可以包含不同类型数据成员的数据结构,在结构类型中可以声明多个不同数据类型的组成部分,C#使用struct来定义一个枚举类型。
③ 数组类型是同一类型数据组成的集合,数组元素没有名称,只能通过索引(或称为下标)来访问,C#支持一维和多维数组。
④ 委托类型是一种定义方法签名的类型,它把一个对象实例和方法都进行封装;可以把委托理解为一种类型安全的函数指针,但它不仅存储对方法入口点的引用,还存储对用于调用方法的对象实例的引用;C#使用delegate来标记一个委托。
(3)简述常用集合类的特点。
答:常用的集合类有ArrayList、Queue、Stack、Hashtable和SortedList。
① 动态数组ArrayList的大小可根据需要自动扩充,允许在其中添加、插入或移除某一范围的元素;其下限始终为零,且始终只是一维的。
② 队列Queue是一种先进先出的数据结构,当插入或删除对象时,对象从队列的一端插入,从另外一端移除。
③ 栈Stack是一种先进后出的数据结构,当插入或删除对象时,只能在栈顶插入或删除。
④ 哈希表Hashtable表示键/值对的集合;在保存集合元素时,首先要根据键自动计算哈希代码,以确定该元素的保存位置,再把元素的值放入相应位置所指向的存储桶中;查找时,再次通过键所对应的哈希代码到特定存储桶中搜索,这样可以极大的提高查找一个元素的效率。
⑤ 有序列表SortedList表示“键/值对”的集合;这些键和值是按键排序,并可按照键和索引访问;SortedList最合适对一列健/值对进行排序,相当于Hashtable和Array的混合。
(4)什么是装箱和拆箱?
答:装箱是指将一个值类型变量转换为一个引用类型的变量;装箱时,首先创建一个引用类型的实例,然后将值类型变量的内容复制给该引用类型实例。
拆箱是指将一个引用类型显式地转换成一个值类型;拆箱时,首先检查这个对象实例是否为给定的值类型的装箱值,然后将这个实例的值复制给相应值类型的变量。
3.上机练习题
(1)编程求指定半径r的圆的面积和周长,并输出计算结果。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseCircle。在Main方法中输入相应代码,具体代码如下所示:
static void Main(string[] args)
{        
         double r,s,l; //半径r、面积s和周长l,均为双精度浮点型
         Console.Write("请输入半径 r:"); 
         r = double.Parse(Console.ReadLine()); 
         s = Math.PI * r * r;
         l = 2 * Math.PI * r;
         Console.WriteLine("半径为{0}的圆,面积={1},周长={2}", r, s, l);
     Console.ReadLine();
}
② 按F5键运行该程序,根据提示输入半径(如5),运行结果如图2.1所示。

图2.1  程序运行结果
(2)已知有枚举类型定义:enum MyEn{a=101,b,c=207,d,e,f,g},编程输出第5个枚举元素的序号值。
答:① 创建一个控制台应用程序exerciseEnum。在代码窗口中,定义枚举MyEn,并在Main方法输入相应代码,Program.cs文件的所有代码如下所示:
using System;
namespace exerciseEnum
{
    enum MyEn 
    { 
        a = 101, b, c = 207, d, e, f, g 
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("MyEn的第5个枚举元素的序号 = {0}", 
(int)MyEn.e);
            Console.ReadLine();
        }
    }
}
② 按F5键运行该程序。
(3)如果m=3,n=5,编程输出下列表达式的值以及m和n的值:
(m=m  )&&(n=n--)
(m=  m)|| (n=--n)
答:① 创建一个控制台应用程序exerciseExpMN。在Main方法中输入如下代码:
static void Main(string[] args)
{
        int m=3,n=5; bool b1,b2;
         Console.WriteLine("m={0}    n={1}", m, n);
         b1 = (m == m  ) && (n == n--);
         Console.WriteLine("(m=m  ) &&(n=n--)的值为{0}", b1);
         Console.WriteLine("m={0}    n={1}", m, n);
         b2 = (m ==   m) || (n == --n);
         Console.WriteLine("(m=  m) ||(n=--n)的值为{0}", b2);
     Console.WriteLine("m={0}    n={1}", m, n);	 Console.ReadLine();
}
② 单击“启动调试”按钮运行程序。
(4)给定如下这些初始变量的声明和赋值语句:int  a = 1, b = 2, c = 3; 编程计算下面的表达式的值: ((((c     --a) * b) != 2) && true)
答:① 创建一个控制台应用程序exerciseExpABC。在Main方法中输入如下代码:
static void Main(string[] args)
{
         int a = 1, b = 2, c = 3;
         Console.WriteLine("a={0}  b={1}  c={2}", a, b, c);
         bool expABC = ((((c     --a) * b) != 2) && true);            
         Console.WriteLine("((((c     --a) * b) != 2) && true)的值
为{0}", expABC);
Console.WriteLine("a={0}  b={1}  c={2}", a, b, c);	 Console.ReadLine();
}
②  单击“启动调试”按钮运行程序。
第3章 Windows窗体与控件
1.选择题
(1)以模式化的方式显示窗体,需要使用_________方法。
     A.Show      B.ShowDialog      C.ShowForm     D.ShowFixed
(2)决定Label控件是否可见的属性是_________。
     A.Hide       B.Show           C.Visible        D.Enabled
(3)把TextBox的_________属性设为True,可使其在运行时接受或显示多行文本。
     A.WordWrap  B.MultiLine        C.ScrollBars     D.ShowMultiLine
(4)利用文本框的_________属性,可以实现密码框的功能。
     A.Password   B.Passwords        C.PasswordChar  D.PasswordChars
(5)如果要为“取消”按钮的文本“Cancel”创建访问键“C”,应将按钮的Text属性设置为“_________”。
     A.&Cancel    B.%Cancel         C.@Cancel      D.^Cancel
答案【B】 【C】 【B】 【C】 【A】
2.思考题
(1)关闭窗体与隐藏窗体有什么区别?
答:关闭窗体与隐藏窗体的区别在于:关闭窗体是将窗体彻底销毁,之后无法对窗体进行任何操作;隐藏窗体只是使窗体不显示,可以使用Show或ShowDialog方法使窗体重新显示。
(2)模式窗体与非模式窗体有什么区别?
答:模式窗体与非模式窗体的区别在于:模式窗体,在其关闭或隐藏前无法切换到该应用程序的其他窗体;非模式窗体,则可以在窗体之间随意切换。
(3)简述Label、Button和TextBox控件的作用。
答:Label(标签)控件的功能是显示不能编辑的文本信息,一般用于在窗体上进行文字说明。Button(按钮)控件是应用程序中使用最多的控件对象之一,常用来接收用户的操作信息,激发相应的事件。TextBox(文本框)控件的主要功能是接受用户输入的信息,或显示系统提供的文本信息。
3.上机练习题
(1)编写一个简单的计算器,能够实现正整数的加减乘除四种运算,设计界面如图3.1所示。

    图3.1 简单计算器
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise简单计算器”,向窗体中添加3个标签、3个文本框和4个按钮,并按照图3.1所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表3.1所示。
表3.1  对象的属性设置
对象	属性名	属性值
Form1	Text	简单计算器
label1~label3	Text	第一个数    第二个数     运算结果
textBox1,textBox2	Name	txtNum1     txtNum2
textBox3	Name	txtResult
	ReadOnly	True
button1~button4	Name	btnAdd      btnSub       btnMul       btnDiv
	Text	            -           ×          ÷
③ 编写代码。依次双击4个按钮,打开代码视图,分别在各个按钮的Click事件处理程序中添加相应代码,如下所示:
private void btnAdd_Click(object sender, EventArgs e)
{ //加
long result = int.Parse(txtNum1.Text)   
int.Parse(txtNum2.Text);
txtResult.Text = result.ToString();
}
private void btnSub_Click(object sender, EventArgs e)
{ //减
long result = int.Parse(txtNum1.Text) – 
int.Parse(txtNum2.Text);
txtResult.Text = result.ToString();
}
private void btnMul_Click(object sender, EventArgs e)
{ //乘
long result = int.Parse(txtNum1.Text) * 
int.Parse(txtNum2.Text);
txtResult.Text = result.ToString();
}
private void btnDiv_Click(object sender, EventArgs e)
{ //除
float result = float.Parse(txtNum1.Text) / 
float.Parse(txtNum2.Text);
txtResult.Text = result.ToString();
}
④ 运行程序。按F5键运行程序,在文本框中输入数据,单击各个运算按钮,查看只读文本框中的输出结果。
(2)编写一个提供常用网址的程序,可以快速访问“百度”、“新浪”、“搜狐”、“腾讯”、 “网易”等网站。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseLinktoWeb,向窗体中添加5个链接标签,并按照图3.2所示调整控件位置和窗体尺寸。

图3.2 提供常用网址的程序
② 设置属性。窗体和各个控件的属性设置如表3.2所示。
表3.2  对象的属性设置
对象	属性名	属性值
Form1	Text	常用网址
linkLabel1~ linkLabel5	Name	lnkBaidu         lnkSina        lnkSohu        lnkQq        lnk163
	LinkArea	3, 13            3, 15          3, 12           3, 10          3, 11
	Text	百度(www.baidu.com)    新浪(www.sina.com.cn)    搜狐(www.sohu.com)
腾讯(www.qq.com)       网易(www.163.com)
③ 编写代码。依次双击5个链接标签,打开代码视图,分别在各个链接标签的LinkClicked事件处理程序中添加相应代码,如下所示:
private void lnkBaidu_LinkClicked(object sender, 
LinkLabelLinkClickedEventArgs e)
{   lnkBaidu.LinkVisited = true;
//使用 Start 方法和一个 URL ,启动默认浏览器打开网页
System.Diagnostics.Process.Start("http://www.baidu.com");
}
private void lnkSina_LinkClicked(object sender, 
LinkLabelLinkClickedEventArgs e)
{   lnkSina.LinkVisited = true;
System.Diagnostics.Process.Start("http://www.sina.com.cn");
}
private void lnkSohu_LinkClicked(object sender, 
LinkLabelLinkClickedEventArgs e)
{   lnkSohu.LinkVisited = true;
System.Diagnostics.Process.Start("http://www.sohu.com");
}
private void lnkQq_LinkClicked(object sender, 
LinkLabelLinkClickedEventArgs e)
{   lnkQq.LinkVisited = true;
System.Diagnostics.Process.Start("http://www.qq.com");
}
private void lnk163_LinkClicked(object sender, 
LinkLabelLinkClickedEventArgs e)
{   lnk163.LinkVisited = true;
System.Diagnostics.Process.Start("http://www.163.com");
}
④ 运行程序。按F5键运行程序,在窗体中依次单击链接文本查看结果。
(3)设计一个转换英文大小写的程序,输入字符时,自动将英文字母分别转换为大写和小写2种格式。
提示:使用Label和TextBox控件设计,利用TextBox控件的TextChanged事件实现即时转换功能,转换后的两个字符串可以利用两个只读的文本框输出。
答:具体步骤如下:
①设计界面。新建一个C#的Windows应用程序,项目名称为exerciseCapital_Lowercase,向窗体中添加3个标签和3个文本框,并按照图3.3所示调整控件位置和窗体尺寸。

图3.3 转换英文大小写的程序
② 设置属性。窗体和各个控件的属性设置如表3.3所示。
表3.3  对象的属性设置
对象	属性名	属性值
Form1	Text	字母大小写转换器
label1~ label3	Text	原始                大写               小写
textBox1~ textBox3	Name	txtOrigin             txtUCase           txtLCase
	ReadOnly	False                True               True
button1	Name	btnExample
	Text	加载范文
③ 编写代码。双击文本框txtOrigin,打开代码视图,在其TextChanged事件处理程序中添加相应代码,如下所示:
private void txtOrigin_TextChanged(object sender, EventArgs e)
{   txtUCase.Text = txtOrigin.Text.ToUpper();
txtLCase.Text = txtOrigin.Text.ToLower();
}
双击按钮btnExample,在其Click事件处理程序中添加相应代码,如下所示:
private void btnExample_Click(object sender, EventArgs e)
{  txtOrigin.Text = "Visual Stuio.NET";
}
④ 运行程序。单击“启动调试”按钮运行程序后,单击“加载范文”按钮,或在文本框中输入英文字母查看结果,如图3.4所示。

图3.4 字母大小写转换器
第4章 顺序结构程序设计
1.选择题
(1)Windows应用程序中,最常用的输入控件是_________。
     A.Label      B.TextBox      C.Button      D.PictureBox
(2)若要显示消息框,必须调用MessageBox类的静态方法_________。
     A.Show      B.ShowDialog   C.ShowBox    D.ShowMessage
(3)PictureBox控件的_________属性可以影响图像的大小及位置关系。
     A.Size       B.Mode        C.SizeMode    D.PictureMode
(4)下列控件中,不能与ImageList组件关联的是_________。
     A.Label      B.Button       C.RadioButton  D.PictureBox
(5)若要使一个控件与图像列表组件关联,需要将该控件的_________属性设置为图像列表组件的名称。
     A.Image     B.Images       C.ImageList    D.ImagesList
答案【B】 【A】 【C】 【D】 【C】
2.思考题
(1)控制台应用程序有哪些输入输出方法?
答:控制台应用程序的数据输入,可以通过Console类的静态方法Read与ReadLine实现;数据输出,可以通过Console类的静态方法Write与WriteLine实现.
(2)TextBox和Label控件的主要区别是什么?
答:从操作程序的用户的角度看,TextBox和Label控件的主要区别在于:Label是一个只能显示数据的控件,而TextBox控件既可以让用户在其中输入数据,也可以显示输出数据。
(3)简述消息框的作用。
答:消息框是一个预定义对话框,用于向用户显示与应用程序相关的信息。当应用程序需要显示一段简短信息(如显示出错、警告等信息)时,使用消息框既简单又方便。只有在用户响应该消息框后,程序才能继续运行下去。
(4)简述PictureBox和ImageList的作用。
答:PictureBox(图片框)控件用于显示位图、GIF、JPEG、图元文件或图标格式的图像,经常用来在窗体上显示一幅图片。ImageList(图像列表)组件相当于一个图片容器,用于存储图像,这些图像随后可由控件(如Label、Button)显示。
3.上机练习题
(1)设计一个程序,将用户输入的金钱数额换算成不同票面(100元、50元、20元、10元、5元、1元)的数量。
要求:利用TextBox输入数额,利用只读的TextBox输出票面的数量;换算时,可利用整除和求余运算;运行界面如图4.1所示。

图4.1 票面换算程序运行界面 
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise票面换算”,向窗体中添加14个标签、7个文本框和1个按钮,并按图4.1所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表4.1所示。
表4.1  对象的属性设置
对象	属性名	属性值
Form1	Text	票面换算
label1~ label14	Text	金钱数额             票面换算如下:
100元      张        50元      张         20元      张
10元       张        5元       张         1元       张
textBox1	Name	txtNum
textBox2~ textBox7	Name	txt100      txt50      txt20       txt10       txt5       txt1
	ReadOnly	True
button1	Name	btnOK
	Text	换算
③ 编写代码。双击btnOK按钮,在代码视图的Click事件处理程序中添加如下代码:
private void btnOK_Click(object sender, EventArgs e)
{
int iNum,iRemain,i100, i50, i20, i10, i5, i1;
iNum = int.Parse(txtNum.Text); //要换算的金额
i100 = iNum / 100;iRemain = iNum % 100;
i50 = iRemain / 50; iRemain = iRemain % 50;
i20 = iRemain / 20; iRemain = iRemain % 20;
i10 = iRemain / 10; iRemain = iRemain % 10;
i5 = iRemain / 5; iRemain = iRemain % 5;
i1 = iRemain;
	//文本框显示各种票面钱币的张数
txt100.Text = i100.ToString();txt50.Text = i50.ToString();
txt20.Text = i20.ToString();  txt10.Text = i10.ToString();
txt5.Text = i5.ToString();    txt1.Text = i1.ToString();
}
④ 运行程序。按F5键运行程序,输入金钱数额,单击“换算”按钮查看结果。
(2)设计一个简单的显示图片及图片文件名的程序。
要求:利用PictureBox显示图片,利用Label显示图片名称,图片文件存放在ImageList组件中,设计界面和运行界面分别如图4.2和图4.3所示。
    
图4.2 设计界面                       图4.3 运行界面
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise图片及名称”,分别向窗体中添加1个Label、1个PictureBox、1个ImageList和1个Button,并按照图4.2和图4.3所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表4.2所示。
表4.2  对象的属性设置
对象	属性名	属性值
Form1	Text	展示图片及其名称
imageList1	Images	添加6幅图片文件
pictureBox1	Name	picChange
	SizeMode	StretchImage
label1	Name	lblName
	Text	图片名称
button1	Name	btnNext
	Text	下一幅
③ 编写代码。在Form1中声明变量,存储imageList1中图像的索引;为Form1添加Load事件处理程序,为按钮btnNext 添加Click事件处理程序,并在其中添加相应代码;具体代码如下所示:
int i = 0; // imageList1中图像的索引
private void Form1_Load(object sender, EventArgs e)
{
picChange.Image=imageList1.Images[i];
lblName.Text = imageList1.Images.Keys[i];
}
private void btnNext_Click(object sender, EventArgs e)
{
i =1;
i = i > imageList1.Images.Count - 1 ? 0 : i;
picChange.Image = imageList1.Images[i];
lblName.Text = imageList1.Images.Keys[i];            
}
 ④ 运行程序。按F5键运行程序,单击“下一幅”按钮查看图片效果及名称。
(3)设计一个Windows窗体应用程序,可以显示具有指定文本和标题的消息框。
要求:利用Label控件提示要输入的内容,利用TextBox控件输入文本和标题,利用MessageBox输出内容。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseMsgBox,向窗体中添加2个标签、2个文本框和1个按钮,并按图4.4所示调整控件位置和窗体尺寸。

图4.4  调用消息框的程序运行界面
② 设置属性。窗体和各个控件的属性设置如表4.3所示。
表4.3  对象的属性设置
对象	属性名	属性值
Form1	Text	定制消息框
label1,label2	Text	消息框的标题:             消息框的文本:
textBox1	Name	txtCaption
textBox2	Name	txtText
	Multiline	True
button1	Name	btnShow
	Text	显示消息框
③ 编写代码。双击按钮btnShow,打开代码视图,在Click事件处理程序中,添加相应代码,如下所示:
private void btnShow_Click(object sender, EventArgs e)
{
MessageBox.Show(txtText.Text, txtCaption.Text);
}
④ 运行程序。单击“启动调试”按钮运行程序,按照标签提示在文本框中输入消息框的标题和文本,然后单击“显示消息框”按钮查看消息框的输出结果。
第5章 选择结构程序设计
1.选择题
(1)if语句中的条件表达式,不能是_________。
     A.关系表达式  B.算术表达式  C.逻辑表达式  D.布尔常量值
(2)switch语句中,用_________来处理不匹配case语句的值。
     A.default      B.anyelse       C.break       D.goto 
(3)下列属性中,RadioButton和CheckBox控件都具有的是_________属性。
     A.ThreeState   B.BorderStyle   C.Checked     D.CheckState
(4)下列控件中,不属于容器控件的是_________。
     A.GroupBox   B.Panel        C.ImageList    D.TabControl
答案【B】 【A】 【C】 【C】
2.思考题
(1)switch语句中,break语句和default标签有什么作用?
答:break语句用于中断选择分支的语句运行,在switch语句中用于跳出switch语句。default标签用来处理不匹配case语句的值,定义default标签可以增强处理相应的异常。
(2)简述RadioButton和CheckBox控件的作用。
答:RadioButton(单选按钮)控件列出了可供用户选择的选项,通常作为一组来工作,同一选项组中的多个选项是相互排斥的,主要用于从多个选项中选择一个选项的功能,是一种“多选一”的控件。
CheckBox(复选框)控件也列出了可供用户选择的选项,用户根据需要可以从选项组中选择一项或多项。
(3)简述GroupBox控件的作用。
答:GroupBox控件用于为其他控件提供可识别的分组,把其他控件用框架框起来,可以提供视觉上的区分和总体的激活或屏蔽特性。
(4)GroupBox和Panel控件的主要区别是什么?
答:二者主要的区别是:只有GroupBox控件可以显示标题,只有Panel控件可以有滚动条;GroupBox控件必须有边框,但Panel控件可以没有边框。
(5)简述TabControl控件的作用。
答:TabControl(选项卡)控件用于显示多个选项卡页,每个选项卡页中可以放置其他控件(包括GroupBox、Panel等容器控件);可以利用TabControl控件来生成多页对话框。
3.上机练习题
(1)编写一个简单的计算器,能够实现整数的加减乘除四种运算,设计界面如图5.1所示。
要求:利用TextBox输入运算数,利用RadioButton设置运算符;使用if语句判断运算符并进行相应运算;除数为零要提示错误;利用只读的TextBox输出运算结果。 

  图5.1 简单计算器
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise简单计算器2”,向窗体中添加3个标签、3个文本框、4个单选按钮和1个按钮,并按照图5.1所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表5.1所示。
表5.1  对象的属性设置
对象	属性名	属性值
Form1	Text	整数的加减乘除
label1~label3	Text	第一个数    第二个数     运算结果
textBox1,textBox2	Name	txtNum1     txtNum2
textBox3	Name	txtResult
	ReadOnly	True
radioButton1~ radioButton4	Name	radAdd      radSub       radMul       radDiv
	Text	            -           ×          ÷
button1	Name	btnCalculate
	Text	运算
③ 编写代码。双击按钮btnCalculate,打开代码视图,在其Click事件处理程序中添加相应代码,如下所示:
private void btnCalculate_Click(object sender, EventArgs e)
{
int n1, n2; //运算数
long r1; double r2;//加减乘的运算结果,除的运算结果
n1 = int.Parse(txtNum1.Text.Trim());
n2 = int.Parse(txtNum2.Text.Trim());
if (radAdd.Checked) //加
{
r1 = n1   n2;  txtResult.Text = r1.ToString();
}
else if(radSub.Checked) //减
{
r1 = n1 - n2;  txtResult.Text = r1.ToString();
}
else if(radMul.Checked) //乘
{
r1 = n1 * n2;  txtResult.Text = r1.ToString();
}
else if(radDiv.Checked)  //除
{
if (n2 == 0)
MessageBox.Show("除数不可以为0", "输入错误");
else
{
r2 = (float)n1 / (float)n2;
txtResult.Text = r2.ToString();
}
}
else 
MessageBox.Show("请选择运算符","操作错误");
}
④ 运行程序。单击“启动调试”按钮运行程序,根据提示进行操作并查看结果。
(2)编写一个简单的成绩转换程序,将百分制成绩x转换为五分制成绩,设计界面如图5.2所示。
要求:利用TextBox输入百分制成绩x;x≥90为“优秀”,80≤ x<90为“良好”,70≤ x<80为“中等”, 60≤ x<70为“及格”,x<60为“不及格”;使用switch语句进行转换;利用只读的TextBox输出五分制成绩。 
提示:switch语句的控制表达式为:x/10。

    图5.2 成绩转换器
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise100to5”,向窗体中添加2个标签、2个文本框和1个按钮,并按图5.2所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表5.2所示。
表5.2  对象的属性设置
对象	属性名	属性值
Form1	Text	成绩转换
label1,label2	Text	百分制成绩             五分制成绩
textBox1	Name	txt100
textBox3	Name	txt5
	ReadOnly	True
button1	Name	btnChange
	Text	转换
③ 编写代码。双击按钮btnChange,打开代码视图,在其Click事件处理程序中添加相应代码,如下所示:
private void btnChange_Click(object sender, EventArgs e)
{
int x;   x = int.Parse(txt100.Text.Trim());
switch (x / 10)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
txt5.Text = "不及格"; break;
case 6:
txt5.Text = "及格"; break;
case 7:
txt5.Text = "中等"; break;
case 8:
txt5.Text = "良好"; break;
case 9:
txt5.Text = "优秀";  break;
case 10:
if (x == 100)
txt5.Text = "优秀";
else
MessageBox.Show("最高分数为100");
break;
default:
MessageBox.Show("有效分数为0—100"); break;
}
}
④ 运行程序。单击“启动调试”按钮运行程序,根据提示进行操作并查看结果。
(3)编写一个简单的大学选课程序,输入学号和姓名后,选择学历,再选择选修课程,然后输出学生的基本信息和选课信息。
要求:利用TextBox控件输入姓名和学号,利用GroupBox和RadioButton控件选择学历(本科或研究生),利用GroupBox和CheckBox控件选择课程;不同学历,可选的课程不同;单击“确定”按钮后,利用消息框输出学生的基本信息和选课信息。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise选课程序”,向窗体中添加2个标签、2个文本框、2个分组框、2个单选按钮、4个复选框和1个按钮,并按照图5.3所示调整控件位置和窗体尺寸。

图5.3 选课程序运行界面
② 设置属性。窗体和各个控件的属性设置如表5.3所示。
表5.3  对象的属性设置
对象	属性名	属性值
Form1	Text	【大学公共课】选课程序
label1,label2	Text	姓名                       学号
textBox1,textBox2	Name	txtName                    txtNo
groupBox1,groupBox2	Text	学历                       选修课程
radioButton1,radioButton2	Name	rad1                        rad2
	Text	本科生                     研究生 
button1	Name	btnOk
	Text	确定
③ 编写代码。首先,在类Form1中自定义两个方法,并在窗体的Load事件处理程序Form1_Load中添加代码,具体代码如下:
private void CourseUndergraduate()
{  //本科生的可选公共课
checkBox1.Checked = checkBox2.Checked = checkBox3.Checked
= checkBox4.Checked = false;
checkBox1.Text = "韩语基础"; checkBox2.Text = "法律基础";
checkBox3.Text = "社交礼仪"; checkBox4.Text = "日语基础";
checkBox4.Visible = true;
}
private void CourseGraduate()
{  //研究生的可选公共课
checkBox1.Checked = checkBox2.Checked = checkBox3.Checked
= checkBox4.Checked = false; 
checkBox1.Text = "翻译与写作"; checkBox2.Text = "多媒体基础"; 
checkBox3.Text = "网页设计"; checkBox4.Visible = false;
}
private void Form1_Load(object sender, EventArgs e)
{
CourseUndergraduate();   //初始化控件对应本科生
}
然后,依次双击单选按钮rad1和按钮btnOk,打开代码视图,分别在rad1_CheckedChanged和btnOk_Click事件处理程序中添加相应代码,如下所示:
private void rad1_CheckedChanged(object sender, EventArgs e)
{
if (rad1.Checked)
CourseUndergraduate();
else
CourseGraduate();
}       
private void btnOk_Click(object sender, EventArgs e)
{
string info,sname,sno,sdegree;
info="";
sname=txtName.Text.Trim();
sno=txtNo.Text.Trim();
if(rad1.Checked)
sdegree="本科生";
else
sdegree="研究生";
if (sname != "" && sno != "")
{
info = sname ",学号" sno ",学历" sdegree "\n";
info  = "所选课程为:";
if(checkBox1.Checked)
info  = checkBox1.Text   " ";
if(checkBox2.Checked)
info  = checkBox2.Text   " ";
if(checkBox3.Checked)
info  = checkBox3.Text   " ";
if(checkBox4.Checked)
info  = checkBox4.Text   " ";
MessageBox.Show(info, "信息确认");
}
else
MessageBox.Show("请输入姓名和学号!", "错误");
}
④ 运行程序。单击“启动调试”按钮运行程序,根据提示进行操作并查看结果。
第6章 循环结构程序设计
1.选择题
(1)C#提供的4种跳转语句中,不推荐使用的是_________。
     A.return       B.goto         C.break       D.continue
(2)下列控件中,不能实现多项选择功能的是_________。
     A.ListBox     B.ComboBox    C.CheckBox   D.CheckedListBox
(3) 如果让计时器每隔10秒触发一次Tick事件,需要将lnterval属性设置为_________。
     A.10          B.100          C.1000       D.10000
(4)已知进度条的下限是0,上限是1000,如果要让进度条显示百分之三十的分段快,需要将Value属性设置为_________。
     A.30         B.30%         C.300         D.0.3  
答案【B】【B】【D】【C】
2.思考题
(1)循环结构中,break语句和contin语句各有什么作用?
答:break(终止)语句用于终止最近的循环语句,将程序控制传递给它所终止语句的后续语句。continue(继续)语句用于结束本次循环,跳过continue之后的其他循环语句,将程序控制传递给循环语句的下一次循环(返回到循环的起始处,并根据循环条件决定是否执行下一次循环)。
(2)简述ListBox和ComboBox控件的作用。
答:ListBox(列表框)控件为用户提供了可选的项目列表,用户可以从列表中选择一个或多个项目。ComboBox(组合框)控件由一个文本框和一个列表框组成,为用户提供了可选的项目列表,用户可以从列表中选择一个项目输入,也可以直接在文本框中输入。
(3)简述Timer组件的作用。
答:Timer(计时器,或称定时器)组件是一种无需用户干预,按一定时间间隔,周期性地自动触发事件的控件。Timer组件通过检查系统时间来判断是否该执行某项任务,经常用来辅助其他控件来刷新显示的时间,也可以用于后台处理。
(4)简述ProgressBar控件的作用。
答:ProgressBar(进度条)控件是个水平放置的指示器,其内部包含多个可滚动的分段块,用于直观地显示某个操作的当前进度。
3.上机练习题
(1)编写一个Windows应用程序,计算n!,n从键盘输入。
要求:利用Textbox输入n,利用for语句实现阶乘的运算,利用只读的Textbox输出n的阶乘。 
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exerciseFactorial”,向窗体中添加2个标签、2个文本框和1个按钮,并按图6.1所示调整控件位置和窗体尺寸。

图6.1 计算阶乘的程序运行界面
② 设置属性。窗体和各个控件的属性设置如表6.1所示。
表6.1  对象的属性设置
对象	属性名	属性值
Form1	Text	计算阶乘
label1,label2	Text	正整数n:                 n的阶乘:
textBox1	Name	txtN
textBox2	Name	txtFact
	ReadOnly	True
button1	Name	btnOk
	Text	计 算
③ 编写代码。双击按钮btnOk,打开代码视图,在其Click事件处理程序中添加相应代码,如下所示:
private void btnOk_Click(object sender, EventArgs e)
{
int n; long fact; //正整数n,其阶乘fact
n = int.Parse(txtN.Text.Trim());
fact = 1;
for (int i = 1; i <= n; i  )
{   fact *= i;  }
txtFact.Text = fact.ToString();
}
④ 运行程序。单击“启动调试”按钮运行程序,按照提示进行操作并查看结果。
(2)编写一个分类统计字符个数的程序,统计输入的字符串中数字、字母和其他字符的个数,运行界面如图6.2所示。
要求:利用String.CopyTo方法将字符串存入字符数组,再使用foreach和if语句遍历并判断数组中的每个字符以进行相应处理;除数为零要提示错误;利用只读的Textbox输出运算结果。 

图6.2 字符分类统计
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseAmountofChar,向窗体中添加1个标签、2个文本框和1个按钮,并按图6.2所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表6.2所示。
表6.2  对象的属性设置
对象	属性名	属性值
Form1	Text	字符分类统计
label1	Text	请输入一个字符串:
textBox1	Name	txtStr
	Text	数字0~9,字母a~z、A~Z,其他字符
textBox2	Name	txtResult
	ReadOnly	True
	Text	数字、字母和其他字符的个数
button1	Name	btnCount
	Text	分类统计
③ 编写代码。双击按钮btnCount,打开代码视图,在其Click事件处理程序中添加相应代码,如下所示:
private void btnCount_Click(object sender, EventArgs e)
{
string s,t;   int n,i,j,k;     char[] c;
s = txtStr.Text; //输入的字符串
n = s.Length;  //输入字符串的长度
i = j = k = 0;
c = new char[n];
s.CopyTo(0, c, 0, n);  //将字符串s存入字符数组c
foreach (char r in c)
{
if (r >= 'A' && r <= 'Z' || r >= 'a' && r <= 'z')
i  ;
else if (r >= '0' && r <= '9')
j  ;
else
k  ;
}
t = String.Format("字母{0}个,数字{1}个,其他字符{2}个",i,j,k);
txtResult.Text = t;
}
④ 运行程序。按F5键运行程序,按照提示进行操作并查看结果。
(3)编写一个计算两个正整数的最大公约数与最小公倍数的程序,运行界面如图6.3所示。
要求:利用Textbox输入两个正整数,利用while语句进行计算。

   图6.3 最大公约数和最小公倍数
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseCommonNumber,向窗体中添加3个标签、2个文本框和1个按钮,并按图6.3所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表6.3所示。
表6.3  对象的属性设置
对象	属性名	属性值
Form1	Text	计算最大公约数和最小公倍数
label1,label2	Text	正整数1:                    正整数2:
textBox1,textBox2	Name	txtA                         txtB
labe3	Name	lblResult
	BorderStyle	Fixed3D
	Text	最大公约数和最小公倍数
button1	Name	btnCal
	Text	计 算
③ 编写代码。双击按钮btnCal,打开代码视图,在其Click事件处理程序中添加相应代码,如下所示:
private void btnCal_Click(object sender, EventArgs e)
{
int a, b, t,i,j;
a = int.Parse(txtA.Text);
b = int.Parse(txtB.Text);
if (a > b) { t = a; a = b; b = t; } // 使a<b
i = a; j = b; // 最大公约数i,最小公倍数j
while (a % i != 0 || b % i != 0) i--;
lblResult.Text = "两个数的最大公约数为:"   i   "\n"; 
while (j % a != 0 || j % b != 0)  j  ;
lblResult.Text  = "两个数的最小公倍数为:"   j;
}
④ 运行程序。单击“启动调试”按钮运行程序,按照提示进行操作并查看结果。
(4)编写一个Windows应用程序,解决我国古代著名的“百钱买百鸡”问题:每只公鸡值5元,每只母鸡值3元,三只小鸡值1元,用100元买100只鸡,公鸡、母鸡和小鸡各买几只?
提示:设能买公鸡x只、母鸡y只、小鸡z只,利用两个方程5x 3y z/3=100和x y z=100,使用二重循环和“穷举法”求各种可能解。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise百钱买百鸡”,向窗体中添加2个标签和1个按钮,并按图6.4所示调整控件位置和窗体尺寸。

图6.4 百钱买百鸡的程序运行界面
② 设置属性。窗体和各个控件的属性设置如表6.4所示。
表6.4  对象的属性设置
对象	属性名	属性值
Form1	Text	百钱买百鸡
label1	Text	我国古代著名的“百钱买百鸡”问题:
    每只公鸡值5元,每只母鸡值3元,三只小鸡值1元。
用100元买100只鸡,公鸡、母鸡和小鸡各买几只?
label2	Name	lblResult
	BorderStyle	Fixed3D
	Text	各种可能解:
button1	Name	btnCal
	Text	计 算
③ 编写代码。双击按钮btnCal,打开代码视图,在其Click事件处理程序中添加相应代码,如下所示:
private void btnCal_Click(object sender, EventArgs e)
{
int x, y, z; //公鸡x只,母鸡y只,小鸡z只 
for(x = 0;x <= 20;x  )
for (y = 0; y <= 33; y  )
{
z = 100 - x - y;
int t = 5*x   3*y   z/3;
if((t == 100) && (z%3==0))
{
string s = String.Format("公鸡{0}只,母鸡{1}只,
小鸡{2}只",x,y,z);
lblResult.Text  = "\n"   s;
}
}
}
④ 运行程序。按F5键运行程序,单击“计算”按钮查看结果,如图6.4所示。
(5)编写一个程序,计算两个指定年份之间的闰年并输出,运行界面如图6.5所示。
要求:利用组合框选择或输入起止年份,起始年份不能大于终止年份;利用列表框输出闰年;窗体左下角显示当前的日期和时间。 

图6.5 计算闰年
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseLeapYear,向窗体中添加4个标签、2个组合框、1个列表框和1个按钮,并按图6.5所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表6.5所示。
表6.5  对象的属性设置
对象	属性名	属性值
Form1	Text	计算指定年份间的闰年
label1~label3	Text	起始年份        终止年份        闰年列表
label4	Name	lblNow
	Text	当前日期和时间
comboBox1,
comboBox2	Name	cbo1            cbo2
	Text	1949            2010
listBox1	Name	lstYear
button1	Name	btnCal
	Text	计算
timer1	Enabled	True
③ 编写代码。首先,双击窗体,打开代码视图,在Form1_Load事件处理程序中添加相应代码,如下所示:
private void Form1_Load(object sender, EventArgs e)
{
int y1=1900, y2=2000;
for (int i = 0; i < 100; i  = 10)
cbo1.Items.Add(y1   i);
for (int i = 0; i < 100; i  = 10)
cbo2.Items.Add(y2   i);           
}
然后,双击按钮btnCal,在其Click事件处理程序中添加相应代码,如下所示:
private void btnCal_Click(object sender, EventArgs e)
{
lstYear.Items.Clear();
int y1, y2;
y1 = int.Parse(cbo1.Text);
y2 = int.Parse(cbo2.Text);
if (y1 > y2)
{
MessageBox.Show("起始年份不能大于终止年份!", "错误");
return;
}
for (int y = y1; y <= y2; y  )
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
lstYear.Items.Add(y);;
}
最后,双击定时器timer1,在其Tick事件处理程序中添加相应代码,如下所示:
private void timer1_Tick(object sender, EventArgs e)
{
lblNow.Text = DateTime.Now.ToString();
}
④ 运行程序。单击“启动调试”按钮运行程序,按照提示进行操作并查看结果。
第7章 面向对象的程序设计基础
1.选择题
(1)面向对象的特点主要概括为         。
A.可分解性、可组合性和可分类性            B.继承性、封装性和多态性
C.封装性、易维护性、可扩展性和可重用性    D. 抽象性、继承性、封装性
(2)要使某个类能被同一个命名空间中的其他类访问,但不能被这个命名空间以外的类访问,该类可以          。
A.不使用任何关键字    	        B.使用private关键
C.使用const关键字 	        D.使用protected关键字
(3)类的字段和方法的默认访问修饰符是__________。
A.public        B.private       C.protected       D.internal
(4)下列关于构造函数的描述中,哪个选项是正确的?__________
A. 构造函数名必须与类名相同      B. 构造函数不可以重载
C. 构造函数不能带参数            D. 构造函数可以声明返回类型
(5)C#中TestClass为一自定义类,其中有以下属性定义:
public void Property{ …… }
使用以下语句创建了该类的对象,并让变量obj引用该对象:
TestClass obj = new TestClass();
那么,可通过__________方式访问类TestClass的Property属性。
A.MyClass.Property             B.obj::Property    
C.obj.Property                  D.obj.Property()
答案【B】【A】【B】【A】【C】
2.思考题
(1)如何理解面向对象程序设计中的类和对象?二者是什么关系?
答:类是具有相同特征的对象的集合,也就是具有相同属性和行为的对象的抽象。
对象是一个封装了状态和行为的实体,具有属性、事件和方法等要素。对象之间能够根据外界的信息进行相应的操作。
类是一种定义了对象行为和外观的抽象模板,对象是类的一个实例;一个类可以创建多个对象,所有对象都是其相关类的实例。
(2)面向对象的主要特点有哪些?
答:面向对象语言的主要特性是封装性、继承性和多态性。
封装性就是把对象的属性和操作结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节,形成一个不可分割的独立单位。从而隐蔽对象的内部细节,只保留有限的对外接口使之与外部发生联系。
继承就是不需要再次编写相同的代码,使得子类具有父类的各种属性和方法。
多态性是将多种不同的特殊行为进行抽象的一种能力,具体是指方法具有相同的名称,可以实现不同的操作。
(3)类的声明格式中包含哪些部分?各有什么意义?
答:类的声明格式中包含访问修饰符、关键字 class、类名 、派生于哪个基类、类体等多个部分。class是定义类的关键字,访问修饰符用来限制类的作用范围或访问级别。“类名”是类的标识符号。冒号后面的“基类”表明所定义的类是从该类派生的一个子类。
类的主体包括类的成员,用来定义类的数据和行为。类的成员分为数据成员和方法成员,具体来说,包括常量、字段、属性、索引器、方法、事件、构造函数、析构函数等。
(4)什么是实例方法?什么是静态方法?
答:必须创建类的实例才能调用的方法称为实例方法,其调用格式为“对象名.方法”。当方法声明中包括static修饰符时,该方法就称为静态方法,其调用格式为“类名.方法”。
(5)类可以使用哪些修饰符?各代表什么含义? 
答:为了控制类的作用范围或访问级别,C#提供了访问修饰符,包括public、internal、private、protected和protected internal。访问修饰符既可以用来限制类和结构,也可以用来限制类成员。具体作用如下: 
① public,定义的成员可以在类的外部进行访问。
② protected,为了方便派生类的访问,但又不希望其他无关类随意访问,就可以使用protected修饰符,将成员声明为保护的。
③ internal,只能在当前程序集中访问。
④ private,只有类内部的成员才可以访问私有成员,在类的外部是禁止直接访问私有成员的,这也是C#中成员声明的默认方式。
⑤ protected internal,成员仅限于当前程序集或该类的派生类访问。
(6)简述new、this、static、ref、out、params、get、set、value这些关键字的作用。 
答:① 用类声明的对象必须使用new运算符调用类的构造函数才能创建实例。
② this表示对当前对象的引用,其类型就是当前类型。
③ static用来声明静态类和静态成员。
④ ref用来声明引用参数,实现数据的传递。
⑤ out关键字来声明输出型参数;输出型参数不需要对实参进行初始化。
⑥ 在形参数组前添加params,所对应的实参可以是数组名或数组元素值的列表。
⑦ get方法返回属性的类型并且没有参数,get用于获取属性值
⑧ set方法返回void且有一个单独的参数,该参数的类型与属性相同。
⑨ 在set方法中,value代表隐式的的参数。
(7)简述构造函数和析构函数的作用。
答:构造函数是类的重要成员,是用于初始化一个对象状态的特殊方法。构造函数与类同名,其主要功能是初始化字段和保证对象在它的生存期里是一个可知状态。
析构函数用于销毁对象。当不再需要某个类的某个对象时,通常希望它所占的存储空间能被收回。析构函数专门用于释放对象占用的系统资源,它是类的特殊成员。
3.上机练习题
(1)构造一个类,可以分别对任意多个整数、小数或字符串进行排序。
答:具体步骤和主要代码如下:
① 创建一个控制台应用程序exerciseSort。
② 在Program.cs文件中定义一个Sort类,并在其中定义三个重载的方法BubbleSort;在Program类的Main函数中测试对任意多个整数、小数或字符串的排序。Program.cs文件的主要代码如下所示:
using System;
namespace exerciseSort
{
   public static  class Sort
    {
        public static  void BubbleSort(params  int[] array) 
        {
		    int length = array.Length;
		    for (int i = 0; i <= length - 2; i  ) 
            {
			    for (int j = length - 1; j >= 1; j--) 
                {  // 对两个元素进行交换
                    if (array[j] < array[j - 1])
                    {   int temp = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = temp;
                    }
				}
			}
            for (int i = 0; i < array.Length; i  )
                Console.Write(array[i]   "\t");
            Console.WriteLine("\n");
		}
         //此处设置double[]、string[]类型数组与int[]相似,代码略 
    class Program
    {
        static void Main(string[] args)
        {
            int[] a = { 2, 3, 5, 8, 9, 1, 0 };
            double[] b = { 1.2, 3.4, 6.5, 9, 12, 18, 1 };
            string[] s = { "China", "Japan", "Viet", "Abc" };
            Sort.BubbleSort(a);
            Sort.BubbleSort(b );
            Sort.BubbleSort(s );
            Sort.BubbleSort(23,34,66,45,11,6);
            Sort.BubbleSort("student", "teacher", "worker", 
"clerk");
            Console.ReadLine();
        }
    }
}
③ 单击“启动调试”按钮运行该程序。
(2)自定义一个时间类,该类包含时、分、秒字段与属性,具有将时间增加1秒、1分和1小时的方法,具有分别显示时、分、秒和同时显示时分秒的方法。
说明:该类定义可用于控制台应用程序,也可用于Windows窗体应用程序。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseClock。
② 在Program.cs文件中定义一个MyClock类,并在其中编写代码,具体代码如下所示:
public class MyClock
    {
        int hours, minutes, seconds;
        public MyClock(int h, int m, int s)
        {
            hours = h;  minutes = m;  seconds = s;
        }
        public void AddHours()
        {  hours  ;  }
        public void AddMinutes()
        {  minutes  ;  }
        public void AddSeconds()
        {  seconds  ;   }
        public int GetHours()
        {  return hours;  }
        public int GetMinutes()
        {  return minutes;  }
        public int GetSeconds()
        {  return seconds;  }
        public string GetClock()
        {
            return hours   "时"   minutes   "分"   seconds   "秒";
        }
    }
③ 单击“启动调试”按钮运行程序。
(3)创建一个Windows应用程序,输入两个正整数,单击“计算”按钮,求出这两个正整数的最大公约数。
要求:将求最大公约数的算法声明为一个静态方法,由“计算”按钮调用。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseHcf,向窗体添加3个文本框、3个标签和1个按钮,并按照图7.1所示调整控件位置和窗体尺寸。

图7.1  设计界面
② 设置属性。窗体和各个控件的属性设置如表7.1所示。
表7.1  对象的属性设置
对象	属性名	属性值
Form1	Text	求最大公约数
label1~ label13	Text	整数1:          整数2:         最大公约数:
textBox1,textBox2	Name	txtNum1          txtNum2
textBox3	Name	txtResult
	ReadOnly	True
button1	Name	btnCal
	Text	计算
③ 编写代码。在Form1类中定义一个求最大公约数的静态方法CountCommonDivisor,并为按钮btnCal添加Click事件处理程序,具体代码如下所示:
public static int CountCommonDivisor(int x1, int x2)
{
int r;
if (x1 < x2) { r = x1; x1 = x2; x2 = r; }
r = x1 % x2;
while (r != 0)
{ x1 = x2; x2 = r; r = x1 % x2; }
return x2;
}
private void btnCal_Click(object sender, EventArgs e)
{
if (txtNum1.Text == "" || txtNum2.Text == "")
return;
int a = Convert.ToInt32(txtNum1.Text);
int b = Convert.ToInt32(txtNum2.Text);
txtResult.Text = Convert.ToString(CountCommonDivisor(a, b));
}
④ 运行程序。按照标签提示在文本框中输入2个整数,单击“计算”按钮查看结果。
(4)构造一个图书类book,能记录和访问书店图书信息,包括标题、作者、价格、库存量等,同时能选择不同的构造函数来初始化类的实例。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseBook。
② 在Program.cs文件中定义一个Book类,并在Program类的Main方法输入相应代码,具体代码如下所示:
public class Book
{
private string title;
public string Title
{
get {  return title; }
set {  title = value; }
}
private string author;
public string Author
{
get { return author; }
set { author = value; }
}
private double  price;
public double  Price
{
get {return price ; }
set 
{
if (value <0) price = 0;
else   price =value ;
}
}
private int count;
public int Count
{
get { return count; }
set
{
if (value < 0) count = 0;
else count = value;
}
}
public Book(string title, string author)
{
this.title = title;  this.author = author;
}
public Book(string title, string author, double  price)
{
this.title = title;  this.author = author;
this.price = price;
}
public Book(string title, string author, int count)
{
this.title = title;  this.author = author;
this.count = count ;
}       
}
class Program
{
static void Main(string[] args)
{
Book book1 = new Book("C#程序设计教程", "刘秋香");
Console.WriteLine("书名:{0},作者:{1}", book1.Title, 
book1.Author);
Book book2 = new Book("C#程序设计教程", "刘秋香", 28.8);
Console.WriteLine("书名:{0},作者:{1},价格:{2}", book2.
Title, book2.Author,book2 .Price );
Book book3 = new Book("C#程序设计教程", "刘秋香", 12);
Console.WriteLine("书名:{0},作者:{1},库存数量:{2}", 
book3.Title, book3.Author,book3 .Count );
Console.ReadLine();
}
}
③ 单击“启动调试”按钮运行程序。
第8章 面向对象的高级程序设计
1.选择题
(1)下面有关虚方法的描述中,正确的是        。
A.虚方法能在程序运行时,动态确定要调用的方法,因而比非虚方法更灵活。
B.在定义虚方法时,基类和派生类的方法定义语句中都要带上virtual修饰符。
C.重写基类的虚方法时,为消除隐藏基类成员的警告,需要带上new修饰符。
D.在重写虚方法时,需要同时带上override和virtual修饰符。
(2)下列方法中,          是抽象方法。
A.static void func( ) { }        B.virtual  void func( ) { }
C.abstract void func( ) { }        D.override  void func( ) { }
(3)下列关于接口的说法中,      是错误的。
A.一个类可以有多个基类和多个基接口。
B.抽象类和接口都不能被实例化。
C.抽象类自身可以定义字段成员而接口不可以。
D.类不可以多重继承而接口可以。
(4)已知类Base、Derived 的定义如下:
class Base 
{ 
public void Hello()
{  System.Console.Write("Hello in Base!");  }
}
class Derived : Base
{  
public new void Hello()
{  System.Console.Write("Hello in Derived!");   }
} 
则语句段“Derived x = new Derived(); x.Hello();”在控制台中的输出结果为_________。
A.Hello in Base!               B.Hello in Base!Hello in Derived!
C.Hello in Derived!             D.Hello in Derived!Hello in Base!
答案【A】【C】【A】【C】
2. 思考题
(1)什么是类的继承?怎样定义派生类?
答:继承涉及到一个基类型和一个派生类型,其中基类型表示的是泛例,而派生类型表示的是特例。特例从泛例中派生出来,也就是说特例继承了泛例。被继承的类叫基类,继承后产生的类叫做派生类。
在C#中,派生类隐式地继承基类的所有成员,包括方法、字段、属性和事件(基类的私有成员、构造函数、析构函数除外),同时可以添加自己的成员来进行功能扩展。
(2)简述创建派生类时,构造函数的调用。
答:C#编译器自动在派生类构造函数中首先自顶向下地调用基类构造函数,以初始化从基类中继承的成员,最后调用自身的构造函数。如果某个派生类中没有明确定义任何构造函数,编译器会自动为之生成一个默认构造函数,并在其中调用其基类构造函数。
(3)怎样定义基类虚方法,并在派生类中重写基类虚方法?
答:在基类中,需要使用关键字virtual将某个方法显式声明为虚方法,然后再在派生类中必须使用override显式声明一个方法以重写某个虚拟方法。方法重写时,必须注意派生类中的方法应该与基类中被重写的方法有相同的方法名、返回值类型、参数列表和访问权限。
(4)抽象方法与虚方法有什么异同?
答:① 当方法前使用了virtual关键字时,它就成为虚拟方法;虚拟方法是多态的基础,在派生类中能够改变方法的执行,改变基类中虚方法的过程叫重写或覆盖。
② 当方法前使用了abstract关键字时,它就成为抽象方法;抽象方法是一个不完全的方法,它只有方法头,没有具体的方法体;抽象方法是一种虚拟方法(但不能用关键字virtual显式声明),是隐含的虚拟,而且必须被派生类实现重写。
③ 抽象方法与虚拟方法的差别在于:虚拟方法有实现,抽象方法没有实现。
(5)什么是抽象类?它有什么特点?它和接口有何异同?
答:抽象类是基类的一种特殊类型,必须用关键字abstract修饰。它除了拥有普通的类成员之外,还有抽象类成员。抽象类成员中的方法和属性,只有声明(使用关键字abstract),而没有实现部分。抽象类永远也不能实例化。
接口像一个抽象类,可以定义方法成员、属性成员、索引器和事件等,但接口不提供对成员的实现,而继承接口的类则必须提供接口成员的实现。可以将接口看做是只包含抽象方法的纯抽象类。接口最终还是需要由类或结构来实现,即要求类要实现接口的抽象方法成员,这与派生类保证要实现它的基类的抽象方法一样。
虽然接口和抽象类在句法和语义上紧密相关,但它们仍有一个重要的区别:接口只能包含抽象方法、抽象属性和抽象索引器,而抽象类还可能包含数据成员,以及完全实现的方法、属性和索引器。
(6)简述通过委托来调用对象方法的基本过程。
答:基本过程如下:
① 使用关键字delegate声明委托类型。
② 委托的实例化。委托是一种特殊的数据类型,必须实例化之后才能用来引用方法。
③ 通过委托变量调用方法。在使用委托对象调用所引用的方法时,必须保证参数的类型、个数和顺序与方法声明匹配。
3. 上机练习题
(1)定义磁盘类Disk及其派生类HardDisk(硬盘)、Flash(闪盘)和CDROM(光盘),在其中定义记录磁盘容量的字段,并通过虚拟方法和重写方法来模拟对磁盘内容的写入和删除。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseDisk。
② 在Program.cs文件中,首先定义Disk类,其中Write是虚拟方法;然后定义3个派生类,在派生类中重写了Write方法;在Program类的Main函数中进行测试。具体代码如下所示:
using System;
namespace exerciseDisk
{
    public class Disk
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name =value; }
        }
        private double capacitySize;
        public double CapacitySize
        {
            get { return capacitySize; }
            set
            {
                if (value <= 0) capacitySize = 0;
                else capacitySize = value;
            }
        }
        public virtual void Write()
        { Console.WriteLine("正在向磁盘中写入……"); }
        public void delete()
        { Console.WriteLine("正在删除磁盘上信息……"); }
    }
    public class HardDisk : Disk
    {
        public override void Write()
        { Console.WriteLine("正在向硬盘上写入信息……"); }
        public new void delete()
        { Console .WriteLine ("正在删除硬盘上信息……"); }
    }
    public class Flash : Disk
    {
        public override void Write()
        { Console.WriteLine("正在向闪存上写入信息……"); }
        public new void delete()
        { Console.WriteLine("正在删除闪存上信息……"); }
    }
    public class CDROM : Disk
    {
        public override void Write()
        { Console.WriteLine("正在向CDROM上写入信息……"); }
    }
    class Program
    {
        static void Main(string[] args)
        {
            HardDisk hd = new HardDisk();
            hd.Write();  hd.delete();
            Flash f = new Flash();
            f.Write();  f.delete();
            CDROM cd = new CDROM();
            cd.Write();
Console.ReadLine();
        }
    }
}
③ 单击“启动调试”按钮运行程序。
(2)设计并编程实现规则平面几何图形(所谓规则是指各边相等,各个内角也相等的等边图形)的继承层次,要求定义一个抽象基类Shape,由它派生出4个派生类:等边三角形、正方形、等边五边形、等边六边形,并通过抽象方法的实现来计算各种图形的面积。
答:具体步骤和主要代码如下:
① 创建一个控制台应用程序exerciseShape。
② 在Program.cs文件中,首先定义抽象基类Shape类,其中getName是虚拟方法,area是抽象方法;然后定义4个派生类,在派生类中重写了getName方法,实现了area方法以计算各种不同图形的面积;在Program类的Main函数中进行测试。具体主要代码如下所示:
using System;
namespace exerciseShape
{
    public abstract class Shape
    {
        private double length;
        public double Length
        {
            get { return length; }
            set
            {
                if (value < 0) length = 0;
                else length = value;
            }
        }
        public abstract double area();
        public virtual string  getName()
        {  return ("这是一个平面图形");  }
    }
    public class EquilateralTriangle : Shape
    {
        public override double area()
        {  return Length * Length * Math.Sqrt(3) / 4;  }
        public override string  getName()
        {  return ("等边三角形");   }
    }
    //此处其他图形的派生类与"等边三角形"相近,代码从略   
    class Program
    {
        static void Main(string[] args)
        {
            double l;  int i;
            EquilateralTriangle mys1 = new EquilateralTriangle();
            Square mys2 = new Square();
            Pentagon mys3 = new Pentagon();
            Hexagon mys4 = new Hexagon();
            Shape[] myShape = { mys1, mys2, mys3, mys4 };
            Console.Write("请输入边长:");
            try
            {
                l = Convert.ToDouble(Console.ReadLine());
Console.WriteLine();
for (i = 0; i < 4; i  )
                {
                    myShape[i].Length = l;
                    Console.WriteLine("{0}的面积是{1}", myShape[i]
.getName(), myShape[i].area());
                }
            }
            catch (Exception e)
            {  Console.WriteLine(e.Message); }
Console.ReadLine();
        }
    }
}
③ 单击“启动调试”按钮运行程序,根据提示输入数据,观察运行结果。
(3)以委托对象作为方法的参数,对学生类对象分别按照姓名、年龄和年级来比较两个学生对象,实现程序以不同的排序方法来输出学生信息。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseStuSort。
② 在Program.cs文件中,首先定义Student类,在其中声明委托CompareFunction,并定义方法SortPrint;在Program类中定义3个与委托具有相同签名的方法CompareName、CompareAge和CompareGrade,然后Main函数中通过选择排序方式(A姓名 、B年龄、C年级)确定SortPrint方法调用的第2个参数(CompareFunction委托类型),以实现不同的排序方式。具体代码如下所示:
public class Student
{
    private string name;
    public string Name
    {
        get { return name; }
    }
    private int age;
    public int Age
    {
        get { return age; }
    }
    private int grade;
    public int Grade
    {
       get { return grade; }
       set { grade = value; }
    }
    public Student(string name, int age, int grade)
    {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
    public static void SortPrint(Student[] students, 
Compareunction compare)
    {
        for (int i = students.Length - 1; i > 0; i--)
             for (int j = 0; j < i; j  )
                 if (compare(students[j], students[j   1]) > 0)
                 {
                     Student s = students[j];
                     students[j] = students[j   1];
                     students[j   1] = s;
                 }
foreach (Student s in students)
            Console.WriteLine(s);
    }
    public override string ToString()
    {
       return string.Format("{0} {1}岁 {2}年级", name, age, grade);
}
    public delegate int CompareFunction(Student s1, Student s2);
}
class Program
{
    static void Main(string[] args)
    {
       Student[] students= new Student[5];
       students [0]= new Student("张静林",18,2);
       students [1]= new Student("李为三",20,3);
       students [2]= new Student("王小菲",18,1);
       students [3]= new Student("刘之远",19,4);
       students [4]= new Student("梅华安",18,1);
       Student.CompareFunction compare;
       Console.WriteLine("请选择排序方式:A姓名  B年龄 C年级");
       char ch = Console.ReadKey().KeyChar;
       if (ch == 'B' || ch == 'b')
           compare = CompareAge;
       else if (ch == 'C' || ch == 'c')
          compare = CompareGrade;
        else
          compare = CompareName;
       Console.WriteLine("\n");
       Student.SortPrint(students, compare);
Console.ReadLine();
   }
   static int CompareName(Student s1,Student s2)
   {  return s1.Name.CompareTo(s2.Name);   }
   static  int  CompareAge(Student s1,Student s2)
   {  return s1.Age - s2.Age;   }
   static  int CompareGrade(Student s1,Student s2)
   {  return s1.Grade - s2.Grade;   }
}
③ 按F5键运行该程序,根据提示输入字母A、B或C,观察运行结果。
(4)构造一个图书类book,能记录和访问书店图书信息,包括标题、作者、价格、库存量等,同时能选择不同的构造函数来初始化类的实例(答案参看第7章习题的设计题(4))。然后,在book类中,添加每卖出一份图书时,就触发一个事件。在订购者中处理该事件,输出销售数据信息。
答:具体步骤如下:
① 打开控制台应用程序exerciseBook。
② 在Program.cs文件中修改Book类,定义BookSales类和SaleDelegate委托,并在Program类的Main方法修改相应代码,具体代码如下所示: 
namespace exerciseBook
{
    public delegate void SaleDelegate(bool sold);//委托
    public class Book
    {
        private string title;
        public string Title
        {
            get { return title; }
            set { title = value; }
        }
        private string author;
        public string Author
        {
            get { return author; }
            set { author = value; }
        }
        private double price;
        public double Price
        {
            get { return price; }
            set
            {
                if (value < 0)  price = 0;
                else  price = value;
            }
        }
        private int count;
        public int Count
        {
            get { return count; }
            set
            {  
                if (value < 0)  count = 0;
                else  count = value;
            }
        }
        private bool sold=false ;
        public bool Sold   //是否卖出1本书
        {
            get {return sold ;}
            set { sold =value ;}
        }
        public Book(string title, string author,bool sold)
        {
            this.title = title;  this.author = author;
            this.sold = sold;
        }
        public Book(string title, string author, double price)
        {
            this.title = title;  this.author = author;
            this.price = price;
        }
        public Book(string title, string author, int count)
        {
            this.title = title;  this.author = author;
            this.count = count;
        }
        public event SaleDelegate OnSale; //声明事件
        public void ChangeSold( )
        {
           if ((OnSale != null)&&(sold == true))
                OnSale (sold  ); //触发事件
        }
    }
    class BookSales
    {
        public void sale(Book book)
        {  //订阅事件
        	book.OnSale  = new SaleDelegate(book_OnSale);
        }
        void  book_OnSale(bool sold)  //处理事件
        { Console.WriteLine("{0}售出1本", DateTime.Now); }
    }
    class Program
    {
        static void Main(string[] args)
        {
            BookSales sale1 = new BookSales();
            Book book1 = new Book("C#程序设计教程", "刘秋香", 12);
            Console.WriteLine("书名:{0},作者:{1},库存数量:{2}", 
book1.Title, book1.Author, book1.Count);
            book1.Sold = true; book1.Count -= 1;
            sale1.sale(book1); book1.ChangeSold();
            Console.WriteLine("书名:{0},作者:{1},库存数量:{2}", 
book1.Title, book1.Author, book1.Count);
            Console.ReadLine();
        }
    }
}
③ 单击“启动调试”按钮运行程序。
第9章 程序调试与异常处理
1.选择题
(1)一般情况下,异常类存放在           中。
A. System.Exception命名空间        B. System.Diagnostics命名空间 
C. System命名空间                 D. 生成异常类所在的命名空间
(2)分析下列程序代码:
int num;
try
{    num = Convert.ToInt32(Console.ReadLine());   }
catch
{    //捕捉异常   }
当输入“abc”时,会抛出           异常。
A. FormatException                  B. IndexOutOfRangException
C. OverflowException                D. TypeLoadException
(3)用户自定义的异常类应该从         类中继承。
A. System.ArgumentException         B. System.IO.IOException
C. System.SystemException           D. System.ApplicationException
(4).NET Framework 中,处理异常是很有用的功能。一个try代码块可以有多个catch块与之对应。在多个catch块中,下面         异常应该最后捕获。
A. System.Exception类              B. System.SystemException类
C. System.ApplicationException类     D. System.StackOverflowException类
答案【C】【A】【D】【A】
2. 思考题
(1)程序错误有哪几类?
答:C#中常见的错误通常可以分成3大类:语法错误、运行时错误和逻辑错误。其中,语法错误比较容易排除,也是一种低级的错误;运行时错误和逻辑错误需要靠经验、调试工具以及不断地深入代码来排除。
(2)什么是异常?所有异常类型都派生于什么类? 
答:在程序运行阶段发生的错误,通常称之为异常,是指程序运行过程出现的非正常事件,是程序错误的一种。
所有的异常都派生自System.Exception类,因此理解Exception类是处理异常的关键。
(3)写出异常类中的两个常用属性,并指出它们分别有什么作用。
答:Exception类常用的属性成员有多个,下面列出常用的两个:
① Message:string类型,获取描述当前异常的消息。
② Source:string类型,获取或设置导致错误的应用程序或对象的名称。
3. 上机练习题
(1)编写一个计算阶乘的程序,当不能存储该数值时,引发异常。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseFactorial。
② 在Program类的Main方法中输入相应代码,当输入数据无效或运算结果超出数据范围时,使用throw抛出异常,然后在catch代码块中进行处理。具体代码如下所示:
class Program
{
static void Main(string[] args)
{
Console.Write("请输入x的值:");
int x, i,y = 1;
try
{
x = Convert.ToInt32(Console.ReadLine());
if (x < 0)  throw new 
FormatException();
for (i = 1; i <= x; i  )
{   y = y * i;
if (y ==0) throw new OverflowException("程序运行
结果超出数据范围");
}
Console.WriteLine("{0}的阶乘是{1}。" ,x,y );
}
catch (FormatException)
{  
Console.WriteLine("输入数据错误,应输入一个正整数"); 
}
catch (OverflowException ex)
{  
Console.WriteLine(ex.Message);  
}
catch (Exception ex)
{  
Console.WriteLine("程序发生意外:"   ex.Message); 
}
Console.ReadLine();
}
}
③  按F5键运行该程序,根据提示输入数据,观察运行结果。
(2)编写一个程序,用来求10个教师的平均工资。要求程序能够捕获数据格式异常和IndexOutOfRangeException异常。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseSalaryAverage。
② 在Program类的Main方法输入相应代码,能够捕获数据格式异常和数组下标越界异常,具体代码如下所示:
class Program
{
static void Main(string[] args)
{
double sum=0; 
double[] array = new double [10];
try
{
for (int i = 0; i <= 10; i  )
{
array[i] =Convert .ToDouble (Console.ReadLine());
sum = sum   array[i];
}
Console.WriteLine("10个人的平均工资是{0}", sum / count);
}
catch(System.FormatException e)
{ 
Console.WriteLine(e.Message ); 
}
catch(System.IndexOutOfRangeException e)
{ 
Console.WriteLine(e.Message ); 
}
Console.ReadLine();
}
}
③  按F5键运行该程序,当输入数据超过10个时,出现异常并进行处理,程序运行结果如图9.1所示。

图9.1  程序运行结果
(3)编写一个程序,求一元二次方程ax2 bx c=0的根,如果方程没有实根,则进行异常处理,输出有关警告信息。
答:具体步骤如下:
① 创建一个控制台应用程序exerciseEquationException。
② 在Program类中编写相应代码,能够处理格式异常、算术异常及方程没有实根的异常,具体代码如下所示:
class Program
{
static double q(double a, double b, double c)
{
double disc; disc = b * b - 4 * a * c;
if (disc<0) 
throw new ArithmeticException ("一元二次方程没有实根");
return Math.Sqrt(disc) / (2 * a);
}
static void Main(string[] args)
{
Console.WriteLine("一元二次方程ax*x   bx   c = 0");
double a,b,c,p,x1,x2;
try
   		{
Console.Write("a = ");
a = Convert.ToDouble(Console.ReadLine());
Console.Write("b = ");
b = Convert.ToDouble(Console.ReadLine());
Console.Write("c = ");  
c  = Convert.ToDouble(Console.ReadLine());
p = -b / (2 * a);
x1 = p   q(a,b,c);   x2 = p - q(a,b,c);
Console.WriteLine ("x1={0},x2={1}",x1,x2 );
}
catch (System.FormatException e)
{  
Console.WriteLine(e.Message);  
}
catch (System.ArithmeticException e)
{  
Console.WriteLine(e.Message);  
}
Console.ReadLine();
}
} 
③ 按F5键运行该程序,根据提示输入a、b、c的值,当b*b-4ac<0时,观察运行结果。
第10章 界面设计
1.选择题
(1)如果要隐藏并禁用菜单项,需要设置___________两个属性。
     A.Visible和Enable      B.Visible和Enabled 
     C.Visiual和Enable      D.Visiual和Enabled
(2)设置需要使用的弹出式菜单的窗体或控件的_________属性,即可激活弹出式菜单。
     A.MenuStrip  B.ContextedMenu   C.ContextMenuStrip  D.ContextedMenuStrip
(3)下列关于RichTextBox控件的说法中,不正确的是的_________。
     A.设计时可以直接将文本赋值给RichTextBox控件
  B.设计时可以直接将图像赋值给RichTextBox控件
  C.运行时可以直接在RichTextBox控件中输入文本
  D.运行时可以直接在RichTextBox控件中嵌入图像
(4)MDI的相关属性中,既可以在【属性】窗口中设置,也可以通过代码设置的是_________属性。
     A.IsMdiChild   B.IsMdiContainer  C.MdiChildren   D.MdiParent
答案【B】【C】【B】【B】
2.思考题
(1)菜单按使用方式可分为哪两种?在C#.NET中使用什么控件来设计这两种菜单?
答:菜单按使用方式有下拉式菜单和弹出式菜单两种。在C#.NET中,使用MenuStrip和ContextMenuStrip控件来设计这两种菜单。
(2)如何快捷有效地让工具栏中的按钮与下拉式菜单中的菜单项具有相同的功能?
答:如果要让工具栏中的按钮与下拉式菜单中的菜单项具有相同的功能,可以在ToolStripButton的Click事件处理程序中,调用菜单项的Click事件方法。
(3)什么是模式对话框?什么是非模式对话框?二者的主要区别是什么?
答:模式对话框是指用户只能在当前的对话框窗体进行操作,在该窗体关闭之前不能切换到程序的其他窗体。非模式对话框是指当前所操作的对话框窗体可以与程序的其他窗体切换。二者区别在于:在对话框被关闭之前,用户能否在同一应用程序的其他窗体进行工作。
(4)举例说明OpenFileDialog和SaveFileDialog控件的Filter属性的作用和格式要求。
答:Filter属性用于获取或设置对话框中的文件名筛选器,即对话框的“文件类型”下拉列表框中出现的选择内容;对于每个筛选选项,都包含由竖线(|)隔开的筛选器说明和筛选器模式,格式为“筛选器说明|筛选器模式”,筛选器模式中用分号来分隔文件类型;多个筛选选项之间由竖线(|)隔开。例如:openFileDialog1.Filter = “Office文件(*.doc;*.xls;*.ppt)|*.doc;*.xls;*.ppt|图片文件(*.gif;*.jpg)|*.gif;*.jpg|所有文件(*.*)|*.*”;
(5)简述Dock和Anchor属性的作用。
答:Dock(停靠)属性用于获取或设置控件停靠的位置和方式,即指示控件的哪些边缘停靠到其父容器并确定控件如何随其父容器一起调整大小;主要用于容器控件和尺寸较大的控件(如RichTextBox)。
Anchor(锚定)属性用于获取或设置控件锚定的位置和方式,即指示控件边缘锚定到其父容器的哪些边缘并确定控件如何随其父容器一起调整大小;主要用在尺寸较小的控件(如Button、Label)中。
(6)什么是SDI和MDI?
答:单文档界面(SDI)和多文档界面(MDI)是Windows应用程序的两种典型结构。SDI(Single Document Interface)一次只能打开一个窗体,一次只能显示一个文档。MDI(Multiple Document Interface)可以在一个容器窗体中包含多个窗体,能够同时显示多个文档,而每个文档都在自己的窗口内显示。
3.上机练习题
(1)为例10-9设计的文本编辑器添加一个工具栏和状态栏,提供对常用功能的快捷操作,并对所进行的操作在状态栏进行说明。
答:具体步骤如下:
① 设计界面。打开例10-9的应用程序MyNotePad,向窗体中添加1个工具栏和1个状态栏,并按照图10.1所示分别在其中添加子项。

图10.1 设计界面 
② 设置属性。工具栏和状态栏的各个子项的属性设置如表10.1所示。
表10.1  对象的属性设置
对象	属性名	属性值
toolStripButton1~
toolStripButton9	Name	btnNew    btnOpen     btnSave     btnCut   btnCopy
btnPaste    btnUndo     btnRedo    btnBold
	Image	设置为相应的小图片,如bmp、ico文件
	ToolTipText	新建       打开       保存       剪切     复制
粘贴       撤消       重复       粗体
toolStripComboBox1
toolStripComboBox2	Name	cboFont                cboSize
	Items	添加6项:Arial、Tahoma、Times New Roman、
黑体、楷体、宋体
添加8项:5、10、16、20、24、36、48、72
	Text	宋体                   20
	ToolTipText	字体                   字号
toolStripStatusLabel1
toolStripStatusLabel2	Name	tsslFile                 tsslDate
	BorderSides	Right                  Left
	Text	文件状态              当前日期
	ToolTipText	文件状态              当前日期
③ 编写代码。首先,为窗体声明一个整型变量来记录新建文档的个数,并为窗体添加Load事件处理程序,具体代码如下所示:
int newCount;
private void Form1_Load(object sender, EventArgs e)
{
newCount = 1;//新建文档的个数
this.Text = "我的记事本——文档"   newCount.ToString();
tsslFile.Text = "新建的文档";
tsslDate.Text = "当前日期:" DateTime.Now.ToShortDateString();
}
然后,分别为工具栏上的9个按钮添加Click事件处理程序,具体代码如下所示:
private void btnNew_Click(object sender, EventArgs e)
{
newCount  = 1; 
this.Text = "我的记事本——文档"   newCount.ToString();
tsslFile.Text = "新建的文档";
rtfMyNP.Text = "";    
}
private void btnOpen_Click(object sender, EventArgs e)
{   打开ToolStripMenuItem_Click(sender, e);    }
private void btnSave_Click(object sender, EventArgs e)
{   保存ToolStripMenuItem_Click(sender, e);   }
private void btnCut_Click(object sender, EventArgs e)
{   rtfMyNP.Cut();   }
private void btnCopy_Click(object sender, EventArgs e)
{   rtfMyNP.Copy();   }
private void btnPaste_Click(object sender, EventArgs e)
{   rtfMyNP.Paste();   }
private void btnUndo_Click(object sender, EventArgs e)
{   if (rtfMyNP.CanUndo)
rtfMyNP.Undo();
else
MessageBox.Show("没有可撤消的操作", "提示");
}
private void btnRedo_Click(object sender, EventArgs e)
{   if (rtfMyNP.CanRedo)
rtfMyNP.Redo();
else
MessageBox.Show("没有可重复的操作", "提示");
}
private void btnBold_Click(object sender, EventArgs e)
{   Font curFont;
if (rtfMyNP.SelectedText != "")
{
curFont = rtfMyNP.SelectionFont;
//FontStyle提示:Regular=0,Bold=1,Italic=2,Underline=4
if (curFont.Bold)
curFont = new Font(curFont, curFont.Style - 1);
else
curFont = new Font(curFont, FontStyle.Bold);
rtfMyNP.SelectionFont = curFont;
}  
}
在例10-9中的原有代码“打开ToolStripMenuItem_Click”事件处理程序中,增加如下一行代码:
tsslFile.Text = "打开的文档"; //状态栏的文件状态
在例10-9中的原有代码“保存ToolStripMenuItem_Click”事件处理程序中,增加如下一行代码:
tsslFile.Text = "文档已保存"; //状态栏的文件状态
最后,为工具栏上的组合框cboFont添加SelectedIndexChanged事件处理程序;组合框cboSize也关联cboFont_SelectedIndexChanged处理程序,可通过属性窗口的事件列表进行操作;cboFont_SelectedIndexChanged处理程序的具体代码如下所示:
private void cboFont_SelectedIndexChanged(object sender, 
EventArgs e)
{
Font curFont;
if (rtfMyNP.SelectedText != "")
{
curFont = new Font(cboFont.Text, float.Parse(cboSize.
Text));
rtfMyNP.SelectionFont = curFont;
}
}
④ 运行程序。按F5键运行程序,打开或新建文档查看结果。
(2)参照例10-10,设计一个录入学生基本档案的MDI程序,并可以将学生的基本档案导出到txt文件,也可以导入txt文件查看学生的基本档案。
要求:运用MenuStrip、ToolStrip、RichTextBox、OpenFileDialog和SaveFileDialog等控件进行界面设计。
答:主要步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为“exercise学生基本档案”;在【解决方案资源管理器】窗口中,将Form1.cs文件重命名为frmMain.cs,再为项目添加四个窗体并命名为frmGR.cs、frmXJ.cs、frmJT.cs、frmQR.cs,然后按照图10.2至图10.6所示分别在5个窗体上添加相应控件并调整控件位置和窗体尺寸。
      
图10.2 主窗体设计界面                   图10.3 个人信息设计界面 
      
图10.4 学籍信息设计界面               图10.5 家庭信息设计界面

图10.6 信息确认设计界面
② 设置属性。5个窗体及其包含控件的属性设置,如表10.2至表10.6所示。
表10.2  frmMain中对象的属性设置
对象	属性名	属性值
frmMain	IsMdiContainer	True
	Text	学生基本档案
信息录入ToolStripMenuItem	DropDownItems	个人信息ToolStripMenuItem,学籍信息ToolStripMenuItem,家庭信息ToolStripMenuItem
toolStrip1	Items	添加4个ToolStripButton对象

toolStripButton1~
toolStripButton4	Name	btnGR      btnXJ       btnJT      btnQR
	DisplayStyle	ImageAndText
	Image	设置为相应的小图片,如bmp、ico文件
	Text	个人信息   学籍信息   家庭信息   信息确认
	ToolTipText	个人信息   学籍信息   家庭信息   信息确认
表10.3  frmGR中对象的属性设置
对象	属性名	属性值
frmGR	Text	学生基本档案——个人信息
label1~ label4	Text	姓名        性别        年龄        籍贯
radioButton1
	Name	radMale
	Text	男
	Checked	true
radioButton2	Name	radFemale
	Text	女
textBox1~ textBox3	Name	txtName           txtAge            txtNativePlace
groupBox1	Text	爱好
checkBox1~ checkBox6	Name	chk1     chk2     chk3     chk4     chk5     chk6
	Text	阅读     音乐     编程     旅游     体育     其它
button1,button2	Name	btnOk           btnExit
	Text	确定           退出
表10.4  frmXJ中对象的属性设置
对象	属性名	属性值
frmXJ	Text	学生基本档案——学籍信息
label1~ label4	Text	学号        班级         院系         专业
textBox1~ textBox4	Name	txtXH       txtBJ         txtYX        txtZY
button1,button2	Name	btnOk        btnExit
	Text	确定         退出
表10.5  frmJT中对象的属性设置
对象	属性名	属性值
frmJT	Text	学生基本档案——家庭信息
label1~ label4	Text	家庭住址     邮政编码    移动电话    固定电话
textBox1~ textBox4	Name	txtZZ         txtYB       txtYD        txtGD
button1,button2	Name	btnOk         btnExit
	Text	确定         退出
表10.6  frmQR中对象的属性设置
对象	属性名	属性值
frmQR	Text	学生基本档案——信息确认
richTextBox1	Name	rtfInfo
	Anchor	Top, Left, Right
button1~button3	Name	btnIn        btnOut        btnExit
	Text	导入        导出          退出
③ 编程的主要步骤:
首先,在frmMain类中声明相关变量来存储所录入的3类信息,以便于“确认信息”窗体访问,并为菜单栏的“个人信息”、“学籍信息”、“家庭信息”、“信息确认”“退出程序”5个菜单项和工具栏的4个按钮添加Click事件处理程序。
第二,在frmGR类中,添加检查必填项和收集信息的方法,为2个按钮添加Click事件处理程序。
第三,在frmXJ类中,添加检查必填项和收集信息的方法,为2个按钮添加Click事件处理程序。
第四,在frmJT类中,添加检查必填项和收集信息的方法,为2个按钮添加Click事件处理程序。
最后,在frmQR类中声明相关变量来存储导入与导出文件的完整路径和扩展名,为窗体添加Load事件处理程序,并为3个按钮添加Click事件处理程序。
④ 运行程序。依次输入3类信息并进行确认,然后导出到txt文件中。
说明:本题代码较多,因篇幅关系只给出主要设计步骤,详细代码可以到清华大学出版社网站关于本书的网址上下载。
第11章 键盘和鼠标操作
1.选择题
(1)C#.NET的所有标准控件都有一个_________方法,通过该方法可以使控件对象获得焦点。
     A.OnFocus    B.Focus      C.Activate     D.ActivateMdiChild
(2)按下并松开键盘上的某个字符键时,不会触发_________事件。
     A.KeyDown   B.KeyPress   C.KeyUp      D.KeyDownUp
(3)若希望窗体能接收键盘事件,必须将窗体的_________属性设为true。
     A.KeyAccept  B.KeyView   C.KeyPreView  D.KeyPreAccept 
(4)在KeyPress事件中,可以通过_________属性来判断按键字符。
     A.KeyCode   B.KeyData    C.KeyChar     D.KeyValue
答案【B】【D】【C】【C】
2.思考题
(1)简述分别按下并松开键盘上的某个字符键和非字符键时,键盘事件发生的顺序。
答:按下并松开键盘上的某个字符键时会依次触发KeyDown、KeyPress、KeyUp事件,按下并松开键盘上的某个非字符键时会依次触发KeyDown和KeyUp事件。
(2)简述对于一次鼠标的单击操作,可能涉及到的鼠标事件的发生顺序。
答:对于一次鼠标的单击(无论哪个按钮)操作,可能涉及到的鼠标事件的发生顺序为:MouseEnter、MouseMove、MouseHover、MouseDown、Click 、MouseClick、MouseUp、MouseHover、MouseMove、MouseLeave。
3.上机练习题
(1)参照【例11-2】设计一个对数字加密程序,程序启动后提示使用方法。
要求:当用户在文本框中输入一个数字字符时,程序自动将其按一定的规律转换成不同的符号字符(数字0~9分别对应不同的符号)并存储到隐藏的标签控件中;单击按钮可以显示标签,如果继续在文本框中输入,则隐藏标签;按BackSpace键可删除光标前一个字符,隐藏标签中的内容随之变化。
提示:利用文本框的KeyDown、KeyPress和KeyUp事件。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称为exerciseEncryptNumber,向窗体中添加4个标签、1个文本框和1个按钮,按照图11.1所示调整控件位置和窗体尺寸。

图11.1 数字加密程序的设计界面

② 设置属性。窗体和各个控件的属性设置如表11.1所示。
表11.1  对象的属性设置
对象	属性名	属性值
Form1	Text	数字加密
label1	Text	加密规则{ 0? 1, 2。 3; 4: 5《 6》 7( 8 ) 9= }
label2	Text	要加密的数字序列

label3	Name	lblEncrypted
	AutoSize	False
	BorderStyle	Fixed3D
	Text	
	Visible	False
label4	Text	双击窗体重置,文本框仅支持依次输入或退格键从最后面删除数字!
textBox1	Name	txtOriginal
button1	Name	btnShow
	Text	加密后的符号序列
③ 编写代码。首先,在Form1中声明相关成员变量,如下所示:
int len=0;  //按键之前的加密字符序列的长度
string txt = ""; //按键之前的原始数字序列
然后,分别为文本框txtOriginal添加KeyDown、KeyPress和KeyUp事件处理程序,代码如下所示:
private void txtOriginal_KeyDown(object sender, KeyEventArgs e)
{
lblEncrypted.Visible = false;
txt = txtOriginal.Text;
len = lblEncrypted.Text.Length;
if (e.KeyCode != Keys.Back)
{
if (e.Control && e.KeyCode == Keys.V)
{
MessageBox.Show("不允许粘贴!", "警告");
txtOriginal.Text = txt;
}
if (e.Control && e.KeyCode == Keys.X)
{
MessageBox.Show("不允许剪切!", "警告");
txtOriginal.Text = txt;
}
}
else
{
if (len == 0)
MessageBox.Show("已无字母可删除!", "提示");
else
lblEncrypted.Text=lblEncrypted.Text.Remove(len-1);
}
}
private void txtOriginal_KeyPress(object sender, 
KeyPressEventArgs e)
{ 
char number = e.KeyChar;
// 加密规则{ 0? 1, 2。 3; 4: 5《 6》 7( 8 ) 9= }
switch (number)
{
case '0':
lblEncrypted.Text  = "?"; break;
case '1':
lblEncrypted.Text  = ","; break;
case '2':
lblEncrypted.Text  = "。"; break;
case '3':
lblEncrypted.Text  = ";"; break;
case '4':
lblEncrypted.Text  = ":"; break;
case '5':
lblEncrypted.Text  = "《"; break;
case '6':
lblEncrypted.Text  = "》"; break;
case '7':
lblEncrypted.Text  = "("; break;
case '8':
lblEncrypted.Text  = ")"; break;
case '9':
lblEncrypted.Text  = "="; break;
}
}
private void txtOriginal_KeyUp(object sender, KeyEventArgs e)
{ //限制文本框只能输入数字0-9,不能输入其他字符
int i = e.KeyValue; // 键盘码说明:0-9[48-57]           
if (e.KeyCode != Keys.Back)
{
if (i < 48 || i > 57)
{
txtOriginal.Text = txt;
txtOriginal.SelectionStart = len;
}
}
}
最后,为按钮添加Click事件处理程序,并为窗体添加DoubleClick事件处理程序,代码如下所示:
private void btnShow_Click(object sender, EventArgs e)
{
lblEncrypted.Visible = true;
}
private void Form1_DoubleClick(object sender, EventArgs e)
{
lblEncrypted.Text="";  
txtOriginal.Clear();
}
④ 运行程序。在文本框中输入数字,单击“加密后的符号序列”按钮查看加密结果。
(2)设计一个欣赏图片的程序,可以同时显示三幅图片。
要求:鼠标指针进入图片框,窗体上的标签显示图片的描述信息;鼠标指针离开图片框,窗体上的标签不显示任何内容。
提示:利用图片框的MouseEnter和MouseLeave事件。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseEnjoyPictures,分别向窗体中添加3个图片框和1个标签,并按照图11.2所示调整标签位置和窗体尺寸。

图11.2 图片欣赏程序的设计界面
 (2) 设置属性。窗体和各个控件的属性设置如表11.2所示。
表11.2  对象的属性设置
对象	属性名	属性值
Form1	Text	图片欣赏
pictureBox1~ 
pictureBox3	Name	pic1          pic2          pic3
	Image	选择相应的图片
	SizeMode	StretchImage
label1	Name	lblInfo
	Text	移动鼠标到图片查看图片的描述信息
(3) 编写代码。首先,依次为3个图片框添加MouseEnter事件处理程序,具体代码如下所示:
private void pic1_MouseEnter(object sender, EventArgs e)
{   
lblInfo.Text = "紫色的葡萄"; 
}
private void pic2_MouseEnter(object sender, EventArgs e)
{   
lblInfo.Text = "卡通动物Kiya"; 
}
private void pic3_MouseEnter(object sender, EventArgs e)
{
lblInfo.Text = "漂亮的鲜花";
}
然后,为图片框pic1添加MouseLeave事件处理程序,并重命名为pic_MouseLeave,然后通过属性窗口的事件列表将其分别关联到三个图片框,该MouseLeave事件处理程序的代码如下所示:
private void pic_MouseLeave(object sender, EventArgs e)
{
lblInfo.Text = "移动鼠标到图片查看图片的描述信息";
}
(4) 运行程序,操作鼠标查看效果。
第12章 数据库编程基础
1.选择题
(1)利用ADO.NET访问数据库,在联机模式下,不需要使用_________对象。
     A.Connection  B.Command      C.DataReader     D.DataAdapter
(2)在脱机模式下,支持离线访问的关键对象是_________。
     A.Connection  B.Command      C.DataAdapter    D.DataSet
(3)直接将一个BindingNavigator控件拖放到窗体中,该控件不具备_________功能。
     A.定位       B.保存           C.添加          D.删除
答案【D】【D】【B】
2.思考题
(1)简述ADO.NET五大核心对象的作用。
答:ADO.NET有5个核心对象的功能如下:Connection(连接),用来建立与特定数据源的连接。 Command(命令),用来对数据源执行SQL命令语句或存储过程。DataReader(数据阅读器),用来从数据源中获取只读、向前的数据流。DataAdapter(数据适配器),用来在数据源和数据集之间交换数据。DataSet(数据集),用来处理从数据源读出的数据,表示数据在内存中的缓存。
(2)简述ADO.NET对于数据库的两种存取模式。
答:ADO.NET对于数据库的存取模式,分为联机模式与脱机模式两种。
① 联机模式是指应用程序在处理数据的过程中,没有与数据库断开,一直与数据库保持连接状态。
② 脱机模式是指应用程序在处理数据之前与数据库连接来获取数据,在数据的处理过程中与数据库断开,处理完数据再与数据库连接来更新数据。
(3)使用SqlConnection对象连接SQL Server数据库时,如果是本地服务器,连接字符串中的服务器名通常有哪几种写法?
答:如果是本地服务器,连接字符串中的服务器名可以写成“.”、“(local)”、“127.0.0.1”或“本地机器名称”。
(4)Command对象有3个常用的成员方法,简述其名称及作用。
答:Command对象有以下三个常用的成员方法:
① ExecuteNonQuery()方法,执行不返回行的SQL命令(Insert、Delete、Update), 并返回受影响的行数;
② ExecuteReader()方法,执行SQL命令(Select),并返回一个生成的DataReader对象;
③ ExecuteScalar()方法,执行SQL命令(Select),并返回查询所得的结果集中第一行的第一列(即单个值)。
(5)简述数据绑定的概念及其两种绑定类型的含义。
答:所谓数据绑定,就是把数据源(如DataTable)中的数据提取出来,显示在窗体的各种控件上。用户可以通过这些控件查看和修改数据,这些修改会自动保存到数据源中。
数据绑定有两种类型:简单数据绑定和复杂数据绑定。
① 简单数据绑定,是指将一个控件绑定到单个数据元素的能力。通常是将TextBox、Label等显示单个值的控件,绑定到数据集中某个DataTable(或BindingSource组件)的某个字段上。
② 复杂数据绑定,是指将一个控件绑定到多个数据元素的能力。通常是将DataGridView、ListBox、ComboBox等显示多个值的控件,绑定到数据集(或BindingSource组件)的多个字段和多条记录。
(6)简述【数据源】窗口的作用。
答:【数据源】窗口显示项目中的数据源,如数据库、Web服务和对象。使用【数据源】窗口,可以轻松地创建数据绑定控件。通过将项(数据表或字段节点)从该窗口拖动到项目中的窗体上,即可创建数据绑定控件的用户界面;还可以通过将项从“数据源”窗口拖动到现有控件,来将现有控件绑定到数据。
3.上机练习题
设计一个简单的个人书籍管理系统,可以实现书籍的查询、添加、修改和删除功能,还可以实现书籍的外借和归还功能。
说明:本题因篇幅关系只给出主要步骤和代码,详细内容可以到清华大学出版社网站关于本书的网址上下载。
答:可以利用Label、TextBox、Button等控件和ADO.NET相关组件以及“数据源”窗口,设计一个MDI应用程序来访问SQL Server数据库以实现个人书籍的基本信息和借阅信息的管理。该个人书籍管理系统主要包括用户管理、个人信息管理、书籍信息管理和借阅信息管理功能;系统由登录界面启动,输入正确的用户名、密码和身份后,才能进入主界面;根据用户身份的不同,可使用的功能不同(管理员可以使用所有功能,普通用户只能管理个人信息和查询书籍信息)。程序运行界面如图12.1至12.10所示。
     
图12.1 登录界面	                         图12.2 系统主界面
    
图12.3 用户管理界面	                  图12.4 个人信息管理界面
  
图12.5 查询书籍信息界面                   图12.6 编辑书籍信息界面
    
图12.7 管理借阅信息界面                   图12.8 借出书籍操作界面
  
图12.9 归还书籍操作界面                   图12.10 管理借阅历史界面
具体步骤如下:
(1) 数据库设计。系统所有数据存储在SQL Server数据库PersonalBooks中,包括UserInfo(用户信息)、BookInfo(书籍信息)、BorrowInfo(借阅信息)和BorrowHistory(借阅历史,即已完成的借出和归还记录)4个数据表。
(2) 程序设计。新建一个C#的Windows应用程序,项目名称设置为“个人书籍管理系统”;将Form1重命名为frmLogin,在项目中再添加8个窗体——frmMain、frmUser、frmPersonal、frmBookQuery、frmBookEdit、frmLendReturn、frmBorrowInfo和frmBorrowHistory;打开【数据源】窗口,利用“数据源配置向导”添加SQL Server数据库PersonalBooks并创建数据集PersonalBooksDataSet。
分别为9个窗体设计界面并编写代码,具体内容如下:
① 登录窗体。分别向窗体中添加3个标签、2个文本框、1个分组框、2个单选按钮和2个按钮,并按照图12.1调整控件位置和窗体尺寸;设置窗体和各个控件的属性,如表12.1所示。
表12.1  对象的属性设置
对象	属性名	属性值
frmLogin	Text	系统登录
label1,label2,label3	Text	欢迎使用【个人书籍管理系统】
用户名 
密 码
textBox1	Name	txtUser
	MaxLength	30

textBox2	Name	txtPwd
	MaxLength	12
	PasswordChar	*
groupBox1	Text	身份

radioButton1	Name	radAdmin
	Text	管理员
	Checked	True

radioButton2 	Name	radCommon
	Text	普通用户
button1,button2	Name	btnLogin           btnExit
	Text	登 录             退 出
下面为登录窗体编写代码。首先,在代码窗口的顶部导入命名空间,代码如下:
using System.Data.SqlClient;
其次,在类frmLogin中声明静态变量,以便于“个人信息管理”窗体访问,代码如下:
public static string userName, password, userIdentity;
然后,为两个按钮添加Click事件处理程序,具体代码如下:
private void btnLogin_Click(object sender, EventArgs e)
{
//1 获取输入的用户名、密码和身份
userName = txtUser.Text;
password = txtPwd.Text;
userIdentity = "";
foreach (Control ctl in groupBox1.Controls)
{
RadioButton rad = (RadioButton)ctl;
if (rad.Checked) userIdentity = rad.Text;
}
//2 访问数据库
string connString = @"Data Source=.;Initial Catalog=
PersonalBooks;Integrated Security=True";
SqlConnection conn = new SqlConnection(connString);
//获取用户名和密码匹配的行的数量的SQL语句
string sql = String.Format("select count(*) from [UserInfo] 
where userName='{0}' and password='{1}' and 
userIdentity='{2}'", userName, password, userIdentity);
try
{
conn.Open();// 打开数据库连接           
SqlCommand comm = new SqlCommand(sql, conn);//创建命令对象
int num =(int)comm.ExecuteScalar();//执行查询,返回匹配的行数
if (num > 0)  //如果有匹配的行,则表明用户名和密码正确
{
frmMain mainForm = new frmMain();// 创建主窗体对象
//根据用户身份,设定可用系统功能
switch (userIdentity)
{
case "管理员":
break;
case "普通用户":
mainForm.mi11用户管理.Visible = false;
mainForm.mi22编辑书籍信息.Visible = false;
mainForm.mi31管理借阅信息.Visible = false;
mainForm.mi32借出与归还操作.Visible = false;
mainForm.mi33管理借阅历史.Visible = false;
break;
}
mainForm.Show();// 显示主窗体                   
this.Hide(); // 登录窗体隐藏
}
else
{
MessageBox.Show("用户名、密码或身份错误!", "登录失败", 
MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "操作数据库出错", 
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
finally
{
conn.Close();// 关闭数据库连接
}
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
② 系统主窗体。向窗体中添加1个菜单,设置窗体和菜单的属性如表12.2所示。
表12.2  对象的属性设置
对象	属性名	属性值
frmMain	IsMdiContainer	True
	Text	个人书籍管理系统
	WindowState	Maximized
menuStrip1	Items	添加3个菜单项——mi1系统管理、mi2书籍管理、mi3借阅管理,其Text属性分别为:系统管理(&S)、书籍管理(&B)、借阅管理(&L)
mi1系统管理	DropDownItems	添加4个子菜单项——mi11用户管理、mi12个人信息管理、toolStripMenuItem1、mi14退出系统,其Text属性分别为:用户管理、个人信息管理、- 、退出系统
mi2书籍管理	DropDownItems	添加2个子菜单项——mi21查询书籍信息、mi22编辑书籍信息,其Text属性分别为:查询书籍信息、编辑书籍信息
mi3借阅管理	DropDownItems	添加3个子菜单项——mi31管理借阅信息、mi32借出与归还操作、mi33管理借阅历史,其Text属性分别为:管理借阅信息、借出与归还操作、管理借阅历史
下面就可以为主窗体编写代码,为窗体添加FormClosing事件处理程序,代码从略。
③ 用户管理窗体。首先,从【数据源】窗口中将UserInfo数据表拖动到窗体上,会自动添加userInfoDataGridView、userInfoBindingNavigator控件及personalBooksDataSet、userInfoBindingSource、userInfoTableAdapter、tableAdapterManager组件;再将UserInfo数据表的userName字段从【数据源】窗口拖动到窗体上,会自动添加userNameLabel和userNameTextBox控件;然后,为窗体添加2个按钮,并设置窗体和各个控件的属性。
④ 个人信息管理窗体。首先,从【数据源】窗口中分别将UserInfo数据表的三个字段拖动到窗体上,会自动添加3个标签、3个文本框、userInfoBindingNavigator控件及相关组件,删除userInfoBindingNavigator控件;然后,为窗体添加2个标签、2个文本框和3个按钮,并设置窗体和各个控件的属性。
⑤ 查询书籍信息窗体。首先,从【数据源】窗口中将BookInfo数据表拖动到窗体上,会自动添加bookInfoDataGridView、bookInfoBindingNavigator控件及相关组件,删除bookInfoBindingNavigator控件中的后面四个工具项(分隔符、添加、删除、保存);然后,为窗体添加两个单选按钮、一个文本框和两个按钮,并设置窗体和各个控件的属性。
⑥ 编辑书籍信息窗体。首先,从【数据源】窗口中将BookInfo数据表拖动到窗体上,会自动添加bookInfoDataGridView、bookInfoBindingNavigator控件及相关组件;然后,为窗体添加两个单选按钮、一个文本框和两个按钮,并设置窗体和各个控件的属性。
⑦ 管理借阅信息窗体。首先,从【数据源】窗口中将BorrowInfo数据表拖动到窗体上,会自动添加borrowInfoDataGridView、borrowInfoBindingNavigator控件及相关组件,删除borrowInfoBindingNavigator控件中的“添加”和“删除”两个工具项;然后,为窗体添加两个单选按钮、一个文本框和两个按钮,并设置窗体和各个控件的属性。
⑧ 借出与归还操作窗体。首先,为窗体添加一个TabControl控件,从【数据源】窗口中分别将BookInfo数据表的6个字段依次拖动到tabPage1上,会自动添加6个标签、6个文本框、bookInfoBindingNavigator控件及相关组件,删除bookInfoBindingNavigator控件中的“添加”、“删除”和“保存”3个工具项;为tabPage1添加两个单选按钮、3个文本框、两个标签和3个按钮,为tabPage2添加2个标签、2个文本框、1个分组框和3个按钮;从【数据源】窗口中分别将BorrowInfo数据表的3个字段依次拖动到tabPage2的分组框groupBox1中,会自动添加3个标签、3个文本框及borrowInfoBindingSource、borrowInfoTableAdapter组件;设置窗体和各个控件的属性。
⑨ 管理借阅历史窗体。首先,从【数据源】窗口中将BorrowHistory数据表拖动到窗体上,会自动添加borrowHistoryDataGridView、borrowHistoryBindingNavigator控件及相关组件;然后,为窗体添加两个单选按钮、一个文本框和两个按钮,并设置窗体和各个控件的属性。
(3) 运行程序。
说明:本题代码较多,因篇幅关系只给出主要设计步骤,详细代码可以到清华大学出版社网站关于本书的网址上下载。

第13章 文件操作
1. 选择题
(1)以下与文件操作相关的类中,        类不是静态类。
A.DriveInfo     B.Path          C.File           D.Directory
(2)以下类中,一般不用于读写二进制文件的是        。
A.FileStream    B.BinaryReader   C.BinaryWriter   D.Stream
答案【A】【D】
2. 思考题
(1)文件与流有哪些区别? 
答:文件(file)是一些具有永久存储性及特定顺序的字节组成的一个有序的、具有名称的集合,它保存在磁盘、光盘、磁带等各种存储设备上。
所谓流(stream),就是连续传输的信息序列。它是一种有序流,因此相对于某一对象,通常把对象接收外界的信息输入称为输入流,相应地从对象向外界输出的信息称为输出流,合称输入/输出流。可以把流看作是一种数据的载体,通过它可以实现数据交换和传输。
对包括文件在内的设备的I/O操作是以流的形式实现的,流是进行数据读写操作的基本对象。
(2)流有哪几种基本操作? 
答:流支持以下3个基本操作:
① 读取(read):表示把数据从流传输到某种数据结构中,例如把数据从流输出到byte数组中;
② 写入(write):表示把数据从某种数据结构传输到流中,例如把byte数组中的数据传输到流中;
③ 定位(seek):表示在流中查询或重新定位当前位置。
(3)在.NET框架中,读写文本文件与二进制文件分别使用什么类?
答:StreamReader和StreamWriter类用于读写文本文件。
FileStream类主要用于二进制文件的读写,此外.NET框架还提供了BinaryReader和BinaryWriter类,实现以二进制方式对文件进行I/O操作。
3. 上机练习题
(1)编写一个程序,判断用户指定的目录是否存在,如果不存在,则创建它。
答:具体步骤如下:
① 新建一个C#的Windows应用程序,项目名称设置为exerciseExistDir,向窗体中添加2个标签、1个文本框和1个按钮,并参照图13.1所示调整控件位置和窗体尺寸。
② 设置属性。窗体和各个控件的属性设置如表13.1所示。
表13.1  对象的属性设置
对象	属性名	属性值
Form1	Text	检查文件是否存在
label1	Text	请输入文件路径:
label2	Name	lblInfo
	Text	
textBox1	Name	txtDir
button1	Name	btnCheck
	Text	检查
③ 编写代码。为按钮btnCheck添加Click事件处理程序,具体代码如下所示:
private void btnCheck_Click(object sender, EventArgs e)
{
        if (File.Exists(textBox1.Text))
            lblInfo = "该文件存在";
        else
        {
            lblInfo.Text = "该文件不存在,已创建它";
            File.Create(textBox1 .Text );
        }
}
④ 运行程序。在文本框中输入文件路径,单击“检查”按钮,运行结果如图13.1所示。

图13.1  程序运行结果
(2)参考记事本,编写Windows应用程序,实现文件的打开、编辑和保存功能。
提示:文本文件的编辑可使用RichTextBox控件实现,打开和保存使用相应的读写器实现。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseNotePad,分别向窗体中添加1个下拉式菜单、1个多格式文本框、1个打开文件对话框和1个保存文件对话框,并按照图13.2所示设置菜单内容和窗体尺寸。

图13.2  程序设计界面
② 设置属性。窗体和各个控件的属性设置如表13.2所示。
表13.2  对象的属性设置
对象	属性名	属性值
Form1	Text	记事本
文件ToolStripMenuItem	DropDownItems	添加三个子菜单项——新建、打开、保存
richTextBox1	Dock	Fill
③ 编写代码。依次双击“新建”、“打开”、“保存”菜单项,在菜单项的Click事件处理程序中,添加相应代码,如下所示:
private void 新建ToolStripMenuItem_Click(object sender, 
EventArgs e)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
richTextBox1.SaveFile(saveFileDialog1.FileName);
richTextBox1.Clear();
}
private void 打开ToolStripMenuItem_Click(object sender, 
EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(openFileDialog1.
FileName, FileMode.Open, FileAccess.Read);
StreamReader m_sr = new StreamReader(fs);
m_sr.BaseStream.Seek(0, SeekOrigin.Begin);
richTextBox1.Text = "";
string strLine = m_sr.ReadLine();
while (strLine != null)
{
richTextBox1.Text  = strLine   "\n";
strLine = m_sr.ReadLine();
}
m_sr.Close();
}
}
private void 保存ToolStripMenuItem_Click(object sender, 
EventArgs e)
{
if(saveFileDialog1.ShowDialog() == DialogResult.OK)
{
FileStream  fs=new FileStream(saveFileDialog1.FileName,
FileMode.OpenOrCreate ,FileAccess .Write );
StreamWriter   m_sw=new StreamWriter (fs );
m_sw.Flush();
m_sw.BaseStream.Seek(0, SeekOrigin.Begin);
m_sw.Write(richTextBox1.Text);
m_sw.Flush();
m_sw.Close();
}
}
④ 运行程序。按F5键运行程序,输入文本后,选择“保存”命令,保存为txt文件,然后找到该文件并打开查看。

第14章 ActiveX控件
1.选择题
(1)创建ActiveX控件,需要使用_________项目模板。
     A.WPF应用程序 		    	B.Windows窗体控件库 
C.Windows窗体应用程序 	    D.类库
(2)Microsoft Web浏览器控件通过调用_________方法来显示指定的网页或文件。
     A.Browse      B.Locate       C.Navigate         D.Open
答案【B】【C】
2.思考题
(1)什么是ActiveX控件?
答:ActiveX控件是由软件提供商开发的可重用的软件组件,是由ActiveX技术创建的一个或多个对象所组成的可重用控件。ActiveX控件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到Web网页或其他应用程序中。
(2)创建ActiveX控件一般需要哪几个步骤?
答:创建ActiveX控件,一般需要经过创建项目、设计界面、编写代码和生成控件四个步骤。
(3)简述3种常见的多媒体ActiveX控件的作用。
答:常见的多媒体ActiveX控件有以下3种:
① Windows Media Player,它是音频视频播放控件,可以实现多种音频与视频格式文件的播放,也可以播放Flash动画和图片文件。
② Shockwave Flash Object,它是Flash动画播放控件,可以实现Flash动画文件的播放。
③ Microsoft Web浏览器,它具有IE浏览器的功能,可以显示网页,也可以播放Flash动画和图片文件。
3.上机练习题
设计一个MDI应用程序,可以播放音频视频文件,也可以播放Flash动画和图片文件,还可以访问指定的网站。
答:具体步骤如下:
① 设计界面。新建一个C#的Windows应用程序,项目名称设置为exerciseMultimedia;在【解决方案资源管理器】窗口中,将Form1.cs文件重命名为frmMain.cs,再为项目添加3个窗体并命名为frmMedia.cs、frmFlash.cs、frmWeb.cs,然后按照图14.1至图14.4所示分别在4个窗体上添加相应控件并调整控件位置和窗体尺寸。
② 设置属性。4个窗体及其包含控件的属性设置,如表14.1至表14.4所示。
      
图14.1 父窗体设计界面                     图14.2 Media播放器设计界面 
      
图14.3 Flash播放器设计界面                    图14.4 Web浏览器设计界面 
表14.1  frmMain中对象的属性设置
对象	属性名	属性值

frmMain	IsMdiContainer	True
	Text	多媒体管理系统
	WindowState	Maximized

menuStrip1	
Items	音频视频播放器ToolStripMenuItem
Flash动画播放器ToolStripMenuItem
Web浏览器ToolStripMenuItem
表14.2  frmMedia中对象的属性设置
对象	属性名	属性值
frmMedia	Text	Windows Media Player 播放器
	MaximizeBox	False
toolStrip1	Items	添加3个ToolStripButton对象

toolStripButton1~
toolStripButton3	Name	btnOpen       btnClose       btnExit
	DisplayStyle	ImageAndText
	Image	设置为相应的小图片,如bmp、ico文件
	Text	打开          关闭           退出
	ToolTipText	打开          关闭           退出
axWindowsMediaPlayer1	Name	axWMP
	Dock	Fill
表14.3  frmFlash中对象的属性设置
对象	属性名	属性值
frmFlash	Text	Flash播放器
toolStrip1	Items	添加3个ToolStripButton对象

toolStripButton1~
toolStripButton3	Name	btnOpen       btnPlayPause     btnExit
	DisplayStyle	ImageAndText
	Image	设置为相应的小图片,如bmp、ico文件
	Text	打开          暂停           退出
	ToolTipText	打开          暂停           退出
axShockwaveFlash1	Name	axSF
	Dock	Fill
表14.4  frmWeb中对象的属性设置
对象	属性名	属性值
frmWeb	Text	Web浏览器

comboBox1	Name	cboURL
	Anchor	Top, Left, Right
	
Items	www.163.com
www.sina.com.cn
www.baidu.com
button1	Name	btnBrowse
	Anchor	Top, Right
	Text	浏览
axWebBrowser1	Name	axWB
	Anchor	Top, Bottom, Left, Right
③ 编写代码。首先,为frmMain窗体的3个菜单项添加Click事件处理程序。具体代码如下所示:
private void 音频视频播放器ToolStripMenuItem_Click(object sender,
EventArgs e)
{
frmMedia frmSub = new frmMedia();
frmSub.MdiParent = this;   frmSub.Show();
}
private void flash动画播放器ToolStripMenuItem_Click(object sender
, EventArgs e)
{
frmFlash frmSub = new frmFlash();
frmSub.MdiParent = this;   frmSub.Show();
}
private void web浏览器ToolStripMenuItem_Click(object sender, 
EventArgs e)
{
frmWeb frmSub = new frmWeb();
frmSub.MdiParent = this;  frmSub.Show();
}
第二,为frmMedia窗体添加Load事件处理程序,并为工具栏上的3个按钮添加Click事件处理程序。具体代码如下所示:
private void frmMedia_Load(object sender, EventArgs e)
{
this.Size = new Size(600, 500);
}
private void btnOpen_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "视频文件(*.avi;*.wmv;*.dat; 
*.mpg;*.mov)|*.avi;*.wmv;*.dat;*.mpg;*.mov|音频文件
(*.wav;*.mp3;*.au;*.midi;*.mid;*.wma)|*.wav;*.mp3;
*.au;*.midi;*.mid;*.wma|所有文件(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string file = openFileDialog1.FileName;
axWMP.URL = file;  //播放文件的路径和名称
this.Text=file.Substring(file.LastIndexOf("\\") 1);
}
}
private void btnClose_Click(object sender, EventArgs e)
{
axWMP.URL = null;
this.Text = "Windows Media Player 播放器";
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
第三,为frmFlash窗体工具栏上的3个按钮添加Click事件处理程序。具体代码如下所示:
private void btnOpen_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "Flash动画文件(*.swf)|*.swf|
所有文件(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string file = openFileDialog1.FileName;
this.Text = file.Substring(file.LastIndexOf("\\")   1);
axSF.Movie = file;
btnPlayPause.Text = "暂停"; 
}
}
private void btnPlayPause_Click(object sender, EventArgs e)
{
if (btnPlayPause.Text == "播放")
{   axSF.Playing = true;  btnPlayPause.Text = "暂停"; }
else
{   axSF.Playing = false; btnPlayPause.Text = "播放"; } 
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
最后,为frmWeb窗体上的“浏览”按钮添加Click事件处理程序,并为组合框cboURL添加SelectedIndexChanged事件处理程序。具体代码如下所示:
private void btnBrowse_Click(object sender, EventArgs e)
{
axWB.Navigate(cboURL.Text);
}
private void cboURL_SelectedIndexChanged(object sender, 
EventArgs e)
{
axWB.Navigate(cboURL.SelectedItem.ToString());
}
④ 运行程序。分别利用父窗体的3个菜单项打开相应的子窗体,根据提示进行操作并查看效果。

第15章 部署Windows应用程序
1.选择题
(1)下列选项中,不属于ClickOnce发布方式的是_________。
     A.从网页发布                B.从媒体发布  
C.从本地磁盘发布            D.从网络文件共享发布
(2)使用Windows Installer部署Windows应用程序,一般使用_________模板或安装向导。
A.CAB项目   B.安装项目    C.Web安装项目    D.合并模块项目
答案 【C】【B】
2.思考题
(1)什么是部署?
答:部署是分发要安装到其他计算机上的已完成应用程序或组件的过程。
(2)分别简述ClickOnce三种发布方式作用。
答:可以采用三种不同的方式发布ClickOnce应用程序:从网页发布、从网络文件共享发布或者从媒体(如 CD-ROM)发布。
① 以“从网页发布”的方式发布ClickOnce应用程序,可以将应用程序部署到Web上,用户通过Web浏览器安装应用程序。
② 以“从网络文件共享发布”的方式发布ClickOnce应用程序,可以将应用程序部署到共享文件夹,用户通过共享文件夹来安装应用程序。
③ 以“从媒体发布”的方式发布ClickOnce应用程序,可以将应用程序部署到CD-ROM或DVD-ROM,来提供应用程序的安装光盘。
3.上机练习题
设计一个简单的访问Access数据库的Windows应用程序,然后分别使用ClickOnce(3种方式)和Windows Installer部署该程序。
答:具体步骤如下:
(1) 设计一个简单的访问Access 2003数据库StudentRecord的Windows应用程序。
① 设计界面并设置属性。新建一个C#的Windows应用程序,项目名称设置为StudentMIS,解决方案名称设置为exerciseStudentMIS;打开【数据源】窗口,利用“数据源配置向导”添加Access 2003数据库StudentRecord并创建数据集StudentRecordDataSet;从【数据源】窗口将studentInfo数据表拖动到窗体上,会自动添加studentInfoDataGridView、studentInfoBindingNavigator控件及相关组件;然后,将窗体的Text属性设置为“学生基本信息管理”,并按照图15.1所示调整控件位置和窗体尺寸。
② 运行程序。单击“启动调试”按钮或按F5键运行程序,运行结果如图15.2所示。
(2) 使用ClickOnce“从网页发布”的方式部署StudentMIS程序。
① 在【解决方案资源管理器】中右击项目,从弹出的快捷菜单中选择“发布…”命令,打开发布向导,如图15.3所示;默认的部署方案是从网页发布,默认服务器是localhost(本机),此处将默认位置更改为“http://localhost/StudentMIS_WebPage/”。
② 单击“下一步”按钮,打开图15.4所示的界面,指定应用程序发布后是否可以脱机使用,即脱机状态下是否可以安装应用程序,此处采用默认选项。
    
图15.1 程序设计界面       图15.2 程序运行界面
  
图15.3 发布向导之“发布位置”          图15.4 发布向导之“脱机或联机”
③ 单击“下一步”按钮,进入发布准备就绪界面,其中说明了要发布到的Web位置。单击“完成”按钮,在应用程序窗体的状态栏会显示发布过程中的一些状态。如果发布正常,则显示图15.5所示的Web安装界面,其中说明了应用程序的名称、版本和发行者。
④ 单击“安装”按钮,会出现一个连接等待,如果是Windows XP操作系统,会出现一个图15.6所示的运行提示。
  
      图15.5  Web安装界面                  图15.6 应用程序安装的安全警告
⑤ 单击“安装”按钮,短暂的等待后就会出现应用程序的运行界面。从“开始”菜单中,可以找到刚才安装的应用程序;在Windows控制面板的“添加或删除应用程序”中,也可以找到该应用程序,并可以对其进行卸载操作。
【说明】发布文件一般位于C:\Inetpub\wwwroot\StudentMIS_WebPage中。
(3) 使用ClickOnce“从网络文件共享发布”的方式部署StudentMIS程序。
① 在【解决方案资源管理器】中右击项目,在弹出的快捷菜单中选择“发布…”命令,打开发布向导,在文本框内输入共享文件路径,其格式为“\\服务器名\文件夹名”,此处输入“\\lqx\StudentMIS_ShareFile”,如图15.7所示。
② 单击“下一步”按钮,打开图15.8所示的界面,指定应用程序发布后如何安装。此处采用默认选项,用户从共享文件安装应用程序。
  
 图15.7 发布向导之“发布位置”           图15.8 发布向导之“如何安装”
③ 单击“下一步”按钮,打开图15.4所示的界面,指定应用程序发布后是否可以脱机使用,此处采用默认选项。
④ 单击“下一步”按钮,进入发布准备就绪界面。单击“完成”按钮,如果发布正常,则会在共享文件夹下生成相关文件和文件夹,并显示图15.9所示的安装界面,该界面与图15.5所示的Web安装界面类似,仅地址栏中的路径不同。
⑤ 单击“安装”按钮,可以进行应用程序的安装。
【说明】共享文件夹需要提前配置好。
(4) 使用ClickOnce“从媒体发布”的方式部署StudentMIS程序。
① 在【解决方案资源管理器】中右击项目,在弹出的快捷菜单中选择“发布…”命令,打开发布向导,在文本框内输入(或者单击“浏览”按钮选择)一个本地文件夹路径,如图15.10所示。
  
   图15.9 共享文件安装界面           图15.10 发布向导之“发布位置”
② 单击“下一步”按钮,打开图15.11所示的界面,指定应用程序发布后如何安装。此处采用默认选项,用户从CD-ROM或DVD-ROM安装应用程序。
③ 单击“下一步”按钮,打开图15.12所示的界面,指定应用程序是否检查更新,此处采用默认选项,不检查更新。
④ 单击“下一步”按钮,,进入发布准备就绪界面。单击“完成”按钮,如果发布正常,则会在指定的文件夹下生成光盘安装需要的相关文件和文件夹,并弹出图15.13所示的文件列表,其中主要文件是setup.exe。
 
图15.11 发布向导之“如何安装”        图15.12 发布向导之“检查更新”

图15.13 媒体安装文件界面
⑤ 双击“setup.exe”文件,可以进行应用程序的安装。将图15.13所示的文件列表刻录到CD-ROM或DVD-ROM,即可完成安装光盘的制作。
(5) 使用Windows Installer方式部署StudentMIS程序。
① 创建部署项目。选择“文件|添加|新建项目”菜单命令,打开【添加新项目】对话框,项目类型选择“其他项目类型”中的“安装和部署”,模板选择“安装项目”,修改安装项目的名称为“StudentMIS_Setup”,并确定安装项目的位置;单击“确定”按钮即可完成安装项目的添加,并出现图15.14所示的【文件系统(…Setup)】窗口,同时可以在【解决方案资源管理器】中看到该安装项目。
② 设置部署项目。在图15.14所示的【文件系统(…Setup)】窗口中,右击左侧的“应用程序文件夹”,从弹出的快捷菜单中选择“添加|项目输出…”命令,会打开【添加项目输出组】对话框,单击“确定”按钮,会生成一个名为“主输出来自学生档案管理系统(活动)”的“输出”类型的文件,在【文件系统(…Setup)】窗口的右侧可以看到该文件;右击 “应用程序文件夹”,从弹出的快捷菜单中选择“添加|文件”命令,从项目文件夹下找到StudentRecord.mdb数据库文件,至此完成所有输出内容的添加;此时的【文件系统(…Setup)】窗口如图15.15所示。
 
图15.14 【文件系统】窗口1             图15.15 【文件系统】窗口2
右击名为“主输出来自StudentMIS(活动)”的文件,从弹出的快捷菜单中选择“创建 主输出来自StudentMIS(活动) 的快捷方式”命令,会生成一个“快捷方式”类型的文件,修改其名称为“学生基本信息管理系统”;将名为“学生基本信息管理系统”的文件拖动到左侧的用户的“程序”菜单中,使程序安装完成后,能够在“程序”菜单中创建一个连接到程序的快捷方式。
在【文件系统(…Setup)】窗口中选定已创建的快捷方式,从【属性】窗口中设置Icon属性,选择要出现在目标计算机上的“Windows 资源管理器”中的应用程序图标。在【解决方案资源管理器】中选定该安装项目,在【属性】窗口中根据实际需要修改安装项目的相关属性:Author为lqx,ProductName为“学生基本信息管理系统”、Title为“【学生基本信息管理系统】安装程序”。至此,完成了部署项目的相关设置。
③ 生成部署项目。在VS2008的“生成”菜单中选择“生成StudentMIS_Setup”命令,在应用程序窗体的状态栏会显示生成部署项目过程中的一些状态。如果生成成功,就完成了安装程序的创建,在安装项目文件夹StudentMIS_Setup下的Debug文件夹(如果源程序采用Release模式编译,则是Release文件夹)中可以看到StudentMIS_Setup.msi和setup.exe文件。
④ 安装程序。双击setup.exe文件将启动安装程序,打开如图15.16所示的安装向导。单击“下一步”按钮,按照提示一步步操作,即可完成程序的安装。安装完成后,单击“开始”按钮,在“程序”菜单中选择“学生基本信息管理系统”命令,即可打开应用程序窗口,测试应用程序的运行效果。

图15.16 【安装向导】对话框

标签:

实例下载地址

Visual C#.NET程序设计教程 习题参考答案

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警