资源描述
/*
C#是这样的一种语言,具有C++的特点,象Java一样的编程风格, 并且象Basic一样的快速开发模型。如果你已经知道了C++,本文会在不到一个小时的时间内让你迅速掌握C#的语法。熟悉Java的括会更好,因为Java的程序结构、打包(Packages)和垃圾收集的概念有助于你更快的了解C#。因此在讨论C#的构造时,我会假定你了解C++。
本文会讨论C#语言的构造与特点,同时会采取简洁的和你能理解的方式使用些代码示例,我们会尽量让你能稍微看看这些代码就能理解这些概念。
注意:本文不是为C#高手(C# gurus)所写. 这是针对在C#学习上还是初学者的文章。
下面是将要讨论的C#问题的目录:
程序结构
命名空间
数据类型
变量
运算符和表达式
枚举
语句(Statements )
类(Classes)和结构(Structs)
修饰符(Modifiers)
属性(Properties)
接口(Interfaces)
方法参数(Function Parameters)
数组(Arrays)
索引器(Indexers)
装箱及拆箱操作
委托(Delegates)
继承和多态
下面的内容将不会在被讨论之列:
C++与C#谁更通用
诸如垃圾回收、线程以及文件处理等概念
数据的类型转换
异常处理
.NET库
-------------------
程序结构
-------------------
这一点象C++,C#是一种对大小写字母敏感的语言,分号“;”是语句间的分隔符。与C++不同的是,C#当中声明代码文件(头文件)与实现代码文件(cpp文件)不是独立存在的,所有代码(类声明和类实现)都位于一个扩展名为cs的文件内。
让我们瞧瞧C#当中的 Hello world 程序是怎样的。
using System;
namespace MyNameSpace
{
class HelloWorld
{
static void Main(string[] args)
{
Console.WriteLine ("Hello World");
}
}
}
在C#当中的每样东西都被封装到一个类中,C#的类又被封装到一个命名空间当中(就象一个文件夹中的文件)。类似于 C++,main方法是你的程序的入口点。C++的main函数调用名称是"main",而C#的main函数是以大写字母M为起点的名称是"Main"。
没有必要把分号分隔符放在类语句块或者结构定义语句块后。这在C++当中被要求,但在C#当中却不是。
-------------------
命名空间
-------------------
每一个类都被包装进一个命名空间。命名空间的概念与C++的完全相同,但在C#当中使用命名空间的频率较C++还高。你可以使用点限定符(dot qulifier)访问一个类。在上面的hello world程序当中MyNameSpace就是一个命名空间。
现在思考这样的一个问题,你想从某些别的类的命名空间当中来访问HelloWorld这个类该如何操作。
这有一个例子:
using System;
namespace AnotherNameSpace
{
class AnotherClass
{
public void Func()
{
Console.WriteLine ("Hello World");
}
}
}
现在,从你的HelloWorld类里你能象这样去访问上面的这个AnotherNameSpace的命名空间:
using System;
using AnotherNameSpace; // you will add this using statement
namespace MyNameSpace
{
class HelloWorld
{
static void Main(string[] args)
{
AnotherClass obj = new AnotherClass();
obj.Func();
}
}
}
在.NET库当中,System是位于顶层的命名空间,别的命名空间都存在这个命名空间之下。默认状态下,存在一个全局的命名空间,因此一个在命名空间外定义的类将直接在这个全局命名空间之下;因此,你能在没有任何点限定符的情况下访问这个类。
你也可以象下面这样定义嵌套的命名空间。
Using
C++当中的"#include"指示被C#的"using"关键字取代,它后面跟着一个命名空间的名字。正如上面的"using System"。"System"是别的所有被封装的命名空间和类中最底层的命名空间。所有对象的基类都是System命名空间内的Object类派生的。
-------------------
变量
-------------------
除以下并别外,C#当中的变量几乎与C++同:
与C++不同,C#变量被访问之前必须被初始化;否则编译时会报错。因此,访问一个未初始化变量是不可能的事。
C#中你不会访问到一个不确定的指针。(译者注:严格说起来C#已经把指针概念异化,限制更严格。所以有些资料上会说C#取消了指针概念)
一个超出数组边界的表达式是不可访问的。
C#中没有全局的的变量或全局函数,全局方式的操作是通过静态函数和静态变量来实现的。
-------------------
数据类型
-------------------
所有C#数据类型都派生自基类Object。这里有两类数据类型:
基本型/内置型 用户自定义型
下面一个C#内置类型列表:
类型 字节数 解释
byte 1 无符号字节型
sbyte 1 有符号字节型
short 2 有符号短字节型
ushort 2 无符号短字节型
int 4 有符号整型
uint 4 无符号整型
long 8 有符号长整型
ulong 8 无符号长整型
float 4 浮点数
double 8 双精度数
decimal 8 固定精度数
string unicode字串型
char unicode字符型
bool 真假布尔型
注意:C#当中的类型范围与C++有所不同;例如,C++的long型是4个字节,而在C#当中是8个字节。同样地,bool型和string型都不同于C++。bool型只接受true和false两种值。不接受任何整数类型。
用户定义类型包括:
类类型(class)
结构类型(struct)
接口类型(interface)
数据类型的内存分配形式的不同又把它们分成了两种类型:
值类型(value Types)
引用类型(Reference Types)
值类型:
值类型数据在栈中分配。他们包括:所有基本或内置类型(不包括string类型)、结构类型、枚举类型(enum type)
引用类型:
引用类型在堆中分配,当它们不再被使用时将被垃圾收集。它们使用new运算符来创建,对这些类型而言,不存在C++当中的delete操作符,根本不同于C++会显式使用delete这个运算符去释放创建的这个类型。C#中,通过垃圾收集器,这些类型会自动被收集处理。
引用类型包括:类类型、接口类型、象数组这样的集合类型类型、字串类型、枚举类型
枚举类型与C++当中的概念非常相似。它们都通过一个enum关键字来定义。
示例:
enum Weekdays
{
Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday
}
类类型与结构类型的比较
除了在内存分配形式上外,类与结构的概念完全与C++相同。类的对象被分配在堆中,并且通过new来创建,结构也是被new创建但却被分配在栈当中。C#当中,结构型适于快速访问和拥有少量成员的数据类型。如果涉及量较多,你应该创建一个类来实现他。
(译者注:这与堆和栈内存分配结构的特点有关。简而言之,栈是一种顺序分配的内存;堆是不一定是连续的内存空间。具体内容需要大家参阅相关资料)
示例:
struct Date
{
int day;
int month;
int year;
}
class Date
{
int day;
int month;
int year;
string weekday;
string monthName;
public int GetDay()
{
return day;
}
public int GetMonth()
{
return month;
}
public int GetYear()
{
return year;
}
public void SetDay(int Day)
{
day = Day ;
}
public void SetMonth(int Month)
{
month = Month;
}
public void SetYear(int Year)
{
year = Year;
}
public bool IsLeapYear()
{
return (year/4 == 0);
}
public void SetDate (int day, int month, int year)
{
}
...
}
-------------------
属性
-------------------
如果你熟悉C++面向对象的方式,你就一定有一个属性的概念。在上面示例当中,以C++的观点来看,Data类的属性就是day、month和year。用C#方式,你可以把它们写成Get和Set方法。C#提供了一个更方便、简单、直接的方式来访问属性。
因此上面的类可以被写成:
using System;
class Date
{
public int Day{
get {
return day;
}
set {
day = value;
}
}
int day;
public int Month{
get {
return month;
}
set {
month = value;
}
}
int month;
public int Year{
get {
return year;
}
set {
year = value;
}
}
int year;
public bool IsLeapYear(int year)
{
return year%4== 0 ? true: false;
}
public void SetDate (int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
}
}
你可在这里得到并设置这些属性:
class User
{
public static void Main()
{
Date date = new Date();
date.Day = 27;
date.Month = 6;
date.Year = 2003;
Console.WriteLine("Date: {0}/{1}/{2}", date.Day,
date.Month,
date.Year);
}
}
-------------------
修饰符
-------------------
你必须已经知道public、private、protected这些常在C++当中使用的修饰符。这里我会讨论一些C#引入的新的修饰符。
readonly(只读)
readonly修饰符仅在类的数据成员中使用。正如这名字所提示的,readonly 数据成员仅能只读,它们只能在构造函数或是直接初始化操作下赋值一次。readonly与const数据成员不同,const 要求你在声明中初始化,这是直接进行的。看下面的示例代码:
class MyClass
{
const int constInt = 100; //直接初始化
readonly int myInt = 5; //直接初始化
readonly int myInt2; //译者注:仅做声明,未做初始化
public MyClass()
{
myInt2 = 8; //间接的
}
public Func()
{
myInt = 7; //非法操作(译者注:不得赋值两次)
Console.WriteLine(myInt2.ToString());
}
}
sealed(密封)
密封类不允许任何类继承,它没有派生类。因此,你可以对你不想被继承的类使用sealed关键字。
sealed class CanNotbeTheParent
{
int a = 5;
}
unsafe(不安全)
你可使用unsafe修饰符来定义一个不安全的上下文。在不安全的上下文里,你能写些如C++指针这样的不安全的代码。看下面的示例代码:
public unsafe MyFunction( int * pInt, double* pDouble)
{
int* pAnotherInt = new int;
*pAnotherInt = 10;
pInt = pAnotherInt;
...
*pDouble = 8.9;
}
-------------------
interface(接口)
-------------------
如果你有COM方面的概念,你会立刻明白我要谈论的内容。一个接口就是一个抽象的基类,这个基类仅仅包含功能描述,而这些功能的实现则由子类来完成。C#中你要用interface关键字来定义象接口这样的类。.NET就是基于这样的接口上的。C#中你不支持C++所允许的类多继承(译者注:即一个派生类可以从两个或两个以上的父类中派生)。但是多继承方式可以通过接口获得。也就是说你的一个子类可以从多个接口中派生实现。
using System;
interface myDrawing
{
int originx
{
get;
set;
}
int originy
{
get;
set;
}
void Draw(object shape);
}
class Shape: myDrawing
{
int OriX;
int OriY;
public int originx
{
get{
return OriX;
}
set{
OriX = value;
}
}
public int originy
{
get{
return OriY;
}
set{
OriY = value;
}
}
public void Draw(object shape)
{
... // do something
}
// class's own method
public void MoveShape(int newX, int newY)
{
.....
}
}
-------------------
Arrays(数组)
-------------------
C#中的数组比C++的表现更好。数组被分配在堆中,因此是引用类型。你不可能访问超出一个数组边界的元素。因此,C#会防止这样类型的bug。一些辅助方式可以循环依次访问数组元素的功能也被提供了,foreach就是这样的一个语句。与C++相比,C#在数组语法上的特点如下:
方括号被置于数据类型之后而不是在变量名之后。
创建数组元素要使用new操作符。
C#支持一维、多维以及交错数组(数组中的数组)。
示例:
int[] array = new int[10]; // 整型一维数组
for (int i = 0; i < array.Length; i++)
array = i;
int[,] array2 = new int[5,10]; // 整型二维数组
array2[1,2] = 5;
int[,,] array3 = new int[5,10,5]; // 整型的三维数组
array3[0,2,4] = 9;
int[][] arrayOfarray = = new int[2]; // 整型交错数组(数组中的数组)
arrayOfarray[0] = new int[4];
arrayOfarray[0] = new int[] {1,2,15};
-------------------
索引器
-------------------
索引器被用于写一个访问集合元素的方法,集合使用"[]"这样的直接方式,类似于数组。你所要做的就是列出访问实例或元素的索引清单。类的属性带的是输入参数,而索引器带的是元素的索引表,除此而外,他们二者的语法相同。
示例:
注意:CollectionBase是一个制作集合的库类。List是一个protected型的CollectionBase成员,储存着集合清单列表。
class Shapes: CollectionBase
{
public void add(Shape shp)
{
List.Add(shp);
}
//indexer
public Shape this[int index]
{
get {
return (Shape) List[index];
}
set {
List[index] = value ;
}
}
}
-------------------
装箱和拆箱操作(Boxing/Unboxing)
-------------------
C#的装箱思想是全新的。上面提到过所有的数据类型,不论内置或用户自定义,全都从命名空间System的一个基类object派生出来。因此把基本的或者原始类型转换成object类型被称做装箱,反之,这种方式的逆操作被称为拆箱。
示例:
class Test
{
static void Main()
{
int myInt = 12;
object obj = myInt ; // 装箱
int myInt2 = (int) obj; // 拆箱
}
}
示例展示了装箱和拆箱操作。一个整型值转换成object类型,然后又转换回整型。当一个值类型的变量需要转换成引用类型时,一个object的箱子会被分配容纳这个值的空间,这个值会被复制进这个箱子。拆箱与此相反,一个object箱子中的数据被转换成它的原始值类型时,这个值将被从箱中复制到适当的存储位置。
*/
第六章 WinForm基础
在通过控制台程序讲解了C#编程的基础知识,类的基础应用和高级设计之后。本章将重点介绍有关Windows窗体应用程序设计的基础知识,本章先从WinForm编程的各种控件的介绍开始,并针对相关的控件或控件组合进行样例程序的讲解,以便让读者从中体会并掌握WinForm编程的基础知识。
6.1 WinForm简介
WinForm是C#设计Windows窗体应用程序的基础,窗体为Windows程序提供一个界面,用户可以在上面绘制各种想要的图形或控件。窗体是容器,为各种控件提供一个布局的平台,各种控件则可以为用户提供输入/输出功能,窗体及各种控件在本质上就是对象,拥有功能完善的属性、方法和事件,用户只需合理的选择其属性、方法或事件进行编程,即可完成一个功能强大的Windows应用程序。
6.2 WinForm基本控件
WinForm窗体及其控件定义在System.Windows.Forms命名空间之中,多数WinForm控件都派生自System.Windows.Forms.Control类。所以要进行Windows应用程序设计,应该先在项目中引入命名空间System.Windows.Forms。当用户在创建一个Windows应用程序时,VS会自动引入此命名空间,这在第一章“第一个WinForm程序”中就可以看到。
6.2.1 窗体及控件
窗体为Windows应用程序提供界面容器,控件是完成输入/输出功能的子窗体。在WinForm中虽然窗体和控件都拥有各自的属性、方法和事件,但因为多数控件和窗体都派生自Control类,因而它们拥有多数相同的属性、方法和事件。
1.控件属性
表6- 1 Control类的基本常用属性
名称
说明
Anchor
获取或设置控件绑定到容器的边缘并确定控件如何随容器一起调整大小。
Dock
获取或设置控件边框停靠到容器并确定控件如何随容器一起调整大小。
BackColor
获取或设置控件的背景色。
BackgroundImage
获取或设置在控件中显示的背景图像。
ContextMenuStrip
获取或设置与此控件关联的上下文菜单。
Enabled
获取或设置一个值,该值指示控件是否可以对用户交互作出响应。
Visible
获取或设置一个值,该值指示是否显示该控件。
Font
获取或设置控件显示的文字的字体。
ForeColor
获取或设置控件的前景色。
Top
获取或设置控件上边缘与容器的工作区上边缘之间的距离。
Left
获取或设置控件左边缘与容器的工作区左边缘之间的距离。
Location
获取或设置该控件的左上角相对于容器的左上角的坐标。
Width
获取或设置控件的宽度。
Height
获取或设置控件的高度。
Size
获取或设置控件的高度和宽度。
Name
获取或设置控件的名称。
Text
获取或设置与此控件关联的文本。
TabIndex
获取或设置在控件的容器的控件的 Tab 键顺序。
Tag
获取或设置包含有关控件的数据的对象。
注:窗体上控件的Name属性只能通过属性面板来改变其值。
2.控件方法
常用的控件方法不多,主要有以下几个:
·Show:显示控件,等同于将Visible设置为true。
·Hide:隐藏控件,等同于将Visible设置为false。
·Focus:将控件设置为当前控件。
·Select:控件激活为当前控件。
·Dispose:释放控件所占用的内存资源。
3.控件事件
表6- 2 Control类的基本常用事件
名称
说明
Click
在单击控件时发生。
DoubleClick
在双击控件时发生。
Enter
进入控件时发生。
GotFocus
在控件接收焦点时发生。
Layout
在控件应重新定位其子控件时发生。
Leave
在输入焦点离开控件时发生。
LostFocus
当控件失去焦点时发生。
MouseClick
在鼠标单击该控件时发生。
MouseDoubleClick
当用鼠标双击控件时发生。
MouseDown
当鼠标指针位于控件上并按下鼠标键时发生。
MouseEnter
在鼠标指针进入控件时发生。
MouseLeave
在鼠标指针离开控件时发生。
MouseMove
在鼠标指针移到控件上时发生。
MouseUp
在鼠标指针在控件上并释放鼠标键时发生。
Resize
在调整控件大小时发生。
一般情况下,每个控件都有一个默认事件,即该控件的最常用事件。当在窗体上双击一个控件时,系统会自动生成该控件的默认事件处理方法,并打开代码窗口。比如按钮Button控件的默认事件为Click,在窗体上双击Name属性为“btnOK”的Button控件时,系统将会为btnOK控件的Click事件生成事件处理方法如下:
private void btnOK_Click(object sender, EventArgs e)
{
}
少数控件通过对默认事件编写事件处理方法就可以完成程序功能,多数控件却不行,因此为控件进行事件编程,最好还是参照在第一章中“第一个WinForm程序”中通过事件面板进行事件选择较好。
4.窗体(Form)
窗体是WinForm应用程序的界面容器,用于布置Windows程序所需的各种控件,当用户新创建一个“Windows应用程序”项目时,VS会自动在项目中添加一个名“Form1”的空白窗体并其打开。新添加的空白窗体如图6- 1所示。
图6- 1 新添加的空白窗体
窗体作为一种对象,除了前面介绍的控件属性、方法和事件之外,还有较多的其他属性、方法和事件,如表6- 3所示。
表6- 3 窗体的常用属性、方法和事件
属性名称
说明
AcceptButton
设置窗体中用于捕获Enter键的按钮。
CancelButton\
设置窗体中用于捕获Ese键的按钮。
ControlBox
设置窗体是否显示控制菜单。
FormBorderStyle
设置窗体的边框样式。
Icon
设置窗体的图标。
IsMdiContainer
设置窗体是否作为MDI窗体容器。
MaximizeBox
设置窗体是否显示最大化按钮。
MinimizeBox
设置窗体是否显示最小化按钮。
Opacity
设置窗体的透明度。
ShowInTaskbar
设置程序运行时,窗体图标是否显示在Windows任务栏中。
StartPosition
设置窗体运行时出现的位置。
WindowState
设置窗体运行时的显示状态。
方法名称
说明
Close
关闭窗体。
事件名称
说明
FromClosed
窗体关闭后发生。
FormClosing
窗体正在关闭时发生。
Load
装载窗体时发生。
Resize
窗体大小改变时发生。
例如Ch06-1:对窗体的FormClosing事件编程程序代码,在单击窗体的“关闭”按钮时,询问是否要关闭窗体。程序代码如下:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("是否关闭窗体?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
e.Cancel = false;
else
e.Cancel = true;
}
程序中先通过消息框MessageBox显示一个信息提示框,询问用户是否关闭当前窗体,如果用户选“是”则关闭当前窗体,如果用户选“否”则不关闭当前窗体。程序运行结果如图6- 2所示。
图6- 2 是否关闭窗体提示
6.2.2 标签、文本框
1.标签(Label)
标签是最常用的基本控件之一,主要用于在窗体上显示文本。在.NetFramework中定义了两类标签:Label和LinkLabel。其中Label是标准的Windows标签,而LinkLabel是带有Internet超链接的标签,在工具箱中分别为和。标签控件有非常多的属性,除了前面介绍的控件属性之外,较为常用的主要如表6- 4中所示。
表6- 4 标签常用属性
属性名称
说明
AutoSize
设置标签是否根据文本改变大小。
BorderStyle
设置标签的边框样式,默认为无边框。
Image
设置在标签上显示的图像。
ImageAlign
设置标签上图像的对齐方式。
TextAlign
设置标签上文本的对齐方式。
在标签的显示文本中可以通过在字母前加“&”字符来设置热键字母,标签通常不进行事件编程。
2.文本框(TextBox)
文本框为Windows应用程序提供一个简单格式的文本编辑区域,是最常用的文本编辑控件,可以完成文本的剪切、复制和粘贴等操作,工具箱中图标为。除了前面介绍的控件属性、方法和事件之外,文本框较为常用的属性、方法和事件如表6- 5所示。
表6- 5 文本框常用属性
属性名称
说明
AcceptsReturn
设置在多行TextBox中按Enter键时,是创建一行新文本还是激活窗体默认按钮。
BackColor
设置TextBox的背景色。
BorderStyle
设置TextBox的边框样式。
Lines
获取多行TextBox中的文本行数。
Multiline
设置TextBox是否允许接收多行文本。
MaxLength
设置TextBox允许接收的最大文本长度。
PasswordChar
设置用于屏蔽单行TextBox的密码字符。
ReadOnly
设置TextBox中文本是否只读文本。
ScrollBars
设置多行TextBox可以出现哪些滚动条,只有当Multilinke为true时才有效。
SelectedText
获取TextBox中选中的文本。
SelectionLength
获取TextBox中选中文本的长度。
SelectionStart
获取TextBox中选中文本的起始位置。
TextAlign
设置TextBox中文本的对齐方式。
WordWrap
设置TextBox中多行文本是否自动换行。
方法名称
说明
AppendText
在当前TextBox的文本末尾添加新文本。
Clear
清除TextBox中的所有文本。
Copy
复制TextBox中的文本到剪贴板。
Cut
剪切TextBox中的文本到剪贴板。
Paste
获取剪贴板中的文本粘贴到TextBox中。
Undo
撤消TextBox中的上一次操作。
事件名称
说明
KeyDown
在TextBox中按下键时发生。
KeyPress
在TextBox中按下键时发生。
KeyUp
在TextBox中释放键时发生。
Change
当TextBox中文本改变时发生。
文本框通常用于完成文件的输入,而标签则用于输出文本框的提示文本。
例如Ch06-2:文字大小写转换程序。
程序界面设计如图6- 3Error! Reference source not found.所示,在窗体上放置两组标签和文本框。然后通过属性面板设置窗体、标签和文本框各属性如表6- 6所示。设置好属性的程序界面如图6- 4所示。
图6- 3程序初始界面
图6- 4设置属性后界面
图6- 5 运行后界面
表6- 6 界面相关控件属性设置
控件名称
属性
设置值
窗体
Text
英文大小写转换程序
标签1
Text
输入
标签2
Text
输出
文本框1
Name
txtInput
文本框2
Name
txtOutput
设置完相关控件属性后,选中文本框txtInput,然后通过事件面板,在事件KeyPrss上双击鼠标,打开代码编写窗口,为文本框txtInput的键盘按键事件编写代码如下。
private void txtInput_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar >= 'A' && e.KeyChar <= 'Z')
txtOutput.Text += char.ToLower(e.KeyChar);
else if (e.KeyChar >= 'a' && e.KeyChar <= 'z')
txtOutput.Text += char.ToUpper(e.KeyChar);
}
程序中通过键盘按键事件参数e获取按下键的字符,判断其是否为大写或小写字母,如果是则其转换为对应小写或大写字母,显示在文本框txtOutput中。程序运行界面如图6- 5所示。
文本框在实际应用中很少进行事件编程。如果要进行丰富格式的文本编辑,可以在程序中使用富文本框(RichTextBox)。
6.2.3 按钮、复选框、单选按钮和框架
1.按钮(Button)
按钮是Windows程序中最常用的控件之一,主要用来为Windows应用程序提供鼠标的单击选择等操作,在工具箱的图标为。按钮常用属性主要有Name和Text,事件主要有Click。
2.复选框(CheckBox)
复选框用来提供一个或多个选项,用户可以在其中选择一项或多项,在工具箱中的图标为。复选框的属性和事件除了前面介绍的而外,属性主要有Appearance、Checked和CheckState,事件主要是Click。
·Appearance:设置复选框的外观状态,使复选框显示为普通状态还是按钮状态。
·Checked:设置或获取复选框是否被选中,bool类型,true为选中,false为未选中。
·CheckState:设置或获取复选框是否被选中,CheckState类型,Checked为选中,unchecked为未选中。
3.单选按钮(RadioButton)
单选按钮用来提供一个或多个选项,在一组单选按钮中,用户只能选择其中一项,在工具箱中的图标为。单选按钮的属性和事件除了前面介绍的而外,属性主要有Checked,事件主要是Click。其中Checked属性和复选框相同。
4.框架(GroupBox)
框架是一个提供了标题文本的容器,主要用来对复选框和单选按扭进行逻辑分组。此外在窗体上使用框架也可以让程序的各种功能在逻辑上表现清楚。
由于单选按钮在一个逻辑组中,只能选中一项,如果要在一个窗体上想同时选中多个单选按钮,则就需要使用框架来对窗体上的单选按钮进行分组。框架通常不进行事件编程,主要属性就是前面介绍的Name、Text、Visible和Enabled。当把框架的Enabled属性设置为false時,框架中的所有控件都将被禁用。
5.综合应用:用户信息注册
本
展开阅读全文