Download presentation
Presentation is loading. Please wait.
Published byHilde Simensen Modified 6年之前
1
第5章 Windows应用程序开发 Windows 窗体是用于 Microsoft Windows 应用程序开发基于.NET 框架的新平台。此框架提供一个有条理的、面向对象的、可扩展的类集,得以开发丰富的 Windows 应用程序。另外,Windows 窗体可作为多层分布式解决方案中的本地用户界面。
2
5.1 开发应用程序的步骤 利用Visual C#开发应用程序一般包括建立项目、界面设计、属性设计、代码设计等步骤。 1.建立项目
在Visual Studio.NET开发环境中选择“文件”菜单,选择“新建”选项中的“项目”,如图5.1所示。 图5.1 “新建项目”对话框
3
1.建立项目 在“项目类型”列表框指定为“Visual C#项目”,在“模板”列表框里指定“Windows应用程序”作为模板,表示将以Visual C#作为程序设计语言,建立一个基于Windows界面的应用程序。同时在“位置”和“名称”列表框选择文件的保存位置和设定项目文件的名字。然后,单击“确定”,返回Visual Studio.NET的主界面,如图5.2所示。 图5.2 集成开发环境
4
5.1 开发应用程序的步骤 2.界面设计 在Visual Studio.NET的主界面,系统提供了一个缺省的窗体。可以通过工具箱向其中添加各种控件来设计应用程序的界面。具体操作是用鼠标按住工具箱需要添加的控件,然后拖放到窗体中即可。本例向窗体中分别添加2个button控件、3个label控件和3个textBox控件,调整各个控件的大小和位置如图5.3所示。 图5.3 应用程序设计界面
5
5.1 开发应用程序的步骤 3.设置属性 首先,在窗体中选中控件。然后在属性窗口设置该控件相应的属性。如表5.1所示。 表5.1 控件属性
6
5.1 开发应用程序的步骤 4.编写程序代码 进入开发环境的代码编辑器。编写代码如下: static void Main() {
Application.Run(new Form1()); } private void button1_Click(object sender, System.EventArgs e) long op1,op2,result; if ( (textBox1.Text == "")|| (textBox2.Text=="")) MessageBox.Show(this,"null","msg",MessageBoxButtons.OK , MessageBoxIcon.Information ); return;
7
4.编写程序代码 try { op1=Convert.ToInt64(textBox1.Text ); op2=Convert.ToInt64(textBox2.Text ); result=op1+op2; textBox3.Text =Convert.ToString (result ); } catch(Exception el) MessageBox.Show (this,el.Message ,"msg",MessageBoxButtons.OK,Message BoxIcon.Warning ); private void button2_Click(object sender, System.EventArgs e) this.Close();
8
4.编写程序代码 同时,系统将自动生成以下代码。 private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.TextBox textBox3;
9
5.1 开发应用程序的步骤 6.保存项目 在“文件”菜单,单击“全部保存”或在工具条中单击“保存”按钮。 5.程序运行与调试
程序运行如图5.4所示。如果运行出错或者运行结果不正确,则查找错误,修正代码后运行。 图5.4 应用程序运行
10
5.2窗体 窗体是标准窗口、多文档界面 (MDI) 窗口、对话框或图形化例程的显示表面。可以将控件放入窗体用来定义用户界面。窗体是对象,这些对象可以定义其外观的属性、定义其行为的方法以及定义其与用户的交互的事件。通过设置窗体的属性以及编写响应其事件的代码,可自定义该对象以满足应用程序的要求。 在 Windows 窗体项目内,窗体是用户交互的主要载体。通过组合不同控件集和编写代码,可从用户得到信息并响应该信息、使用现有数据存储、以及查询并写回到用户本地计算机上的文件系统和注册表中。窗体可以在“代码编辑器”中创建,也可以使用“Windows 窗体设计器”创建和修改窗体。
11
5.2.1 创建Windows应用程序项目 在“文件”菜单上选择 “新建”,然后选择“项目”。在左侧窗格中,选择所需语言。在右侧窗格中,选择“Windows 应用程序”。“Windows 窗体设计器”打开,显示所创建项目,如图5.5所示。 图5.5 创建的项目
12
5.2.1 创建Windows应用程序项目 系统包含三种样式窗体:
(1) 单文档界面 (SDI): 例如,Microsoft Windows 中包括的“写字板”应用程序就是SDI类型的界面。在“写字板”中,只能打开一个文档;打开另一个文档自动关闭一个已经打开的文档。 (2) 多文档界面(MDI):例如,Microsoft Word、Microsoft Excel等就是多文档界面 (MDI) 应用程序。 (3) 资源管理器样式界面:例如,Windows 资源管理器。 Windows 应用程序可能需要多个窗体,可以向项目添加多个窗体。添加从“Forms”类继承的Windows 窗体,只要在“解决方案资源管理器”中,右击项目并选择“添加”,然后选择“Windows 窗体”。添加从以前创建的窗体类继承的 Windows 窗体只要在“解决方案资源管理器”中,右击项目并选择“添加”,然后选择“继承的窗体”。 在“Windows 窗体设计器”内,可查看项目内的窗体及其控件。
13
5.2.2 选择启动窗体 从“新建项目”对话框中选择“Windows 应用程序”所创建的窗体,在默认情况下将成为启动窗体。启动窗体可以根据需要进行设置或更改,在“解决方案资源管理器”中,右击项目并选择“属性”,“项目”属性页打开。选择“通用”属性,从“启动对象”下拉列表中选择要作为启动窗体的窗体。
14
5.2.3 窗体属性 1.Visible 属性 窗体的可见性通常由 Visible 属性控制。在事件中,如果希望 Windows 应用程序的主窗体在应用程序启动时不可见,将会发现将它的 Visible 属性设置为假的方法无效,因为通常启动窗体的生存期决定了应用程序的生存期,只要将应用程序的启动变为一个模块,这样就可以随意使窗体可见(和不可见),因为当“关闭”模块时,应用程序的生存期也随之结束。 2.TopMost 属性 TopMost 属性控制窗体是否为最顶端的窗体。请注意,即使最顶端的窗体不处于活动状态,它也会浮在其他非最顶端窗体之前。 在设计时使窗体成为 Windows 窗体应用程序中最顶端的窗体,只要在“属性”窗口中将 TopMost 属性设置为 true。 以编程方式使窗体成为 Windows 窗体应用程序中最顶端的窗体,只要采用将 TopMost 属性设置为 true的代码:例如: public void MakeOnTop() { myTopForm.TopMost = true; }
15
5.2.3 窗体属性 3.FormBorderStyle 属性 当确定 Windows 窗体的外观时,有几种边框样式可供选择,如表5.2。
表5.2 窗体的边框风格 注意:所有上述边框样式(除“无”设置外),都在标题栏的右侧有一个“关闭”框。
16
5.2.3 窗体属性 4.Location 属性 Location 属性值可指定窗体在计算机屏幕上的显示位置。它以像素为单位指定窗体左上角的位置。还需要设置 StartPosition 属性,以指示显示区域的边界。 Windows应用程序的 StartPosition 属性的默认设置是“WindowsDefaultLocation”,该设置通知操作系统在启动时根据当前硬件计算该窗体的最佳位置。另一种选择是将 StartPosition 属性设置为 Center,然后在代码中更改窗体的位置。 ● 使用“属性”窗口定位窗体 在 “属性”窗口中,从下拉菜单选择窗体。将窗体的 StartPosition 属性设置为 Manual。 为Location属性键入值(以逗号分隔)来定位该窗体,其中第1个数字(X)是到显示区域左边界的距离(像素),第2个数字(Y)是到显示区域上边界的距离(像素)。 ● 以编程方式定位窗体 在运行时,将窗体的Location属性设置为Point来定义窗体的位置,例如: Form1.Location = new Point (100, 100); 或使用Left子属性(用于 X 坐标)和Top子属性(用于Y坐标)更改窗体位置的X坐标和 Y坐标。例如,将窗体的X坐标调整为300个像素点: Form1.Left = 300;
17
4.Location 属性 控件是窗体上的一个组件,用于显示信息或接受用户输入。大多数窗体都是通过将控件添加到窗体表面来定义控件的位置。
● 窗体中控件位置 控件是窗体上的一个组件,用于显示信息或接受用户输入。大多数窗体都是通过将控件添加到窗体表面来定义控件的位置。 ● 将控件拖动到窗体上 在“工具箱”中,单击所需控件并将其拖动到窗体上。也可双击“工具箱”中的控件,将该控件按其默认大小添加到窗体的左上角。 在运行时可动态地将控件添加到窗体中。在下面的示例中,当单击“按钮”(Button) 控件时,“文本框”(TextBox) 控件将添加到窗体中。 在窗体的类的内部,在处理按钮的 Click 事件的方法中,插入类似于以下内容的代码,以添加对控件变量的引用,设置控件的“位置”,然后添加该控件: private void button1_Click(object sender, System.EventArgs e) { TextBox myText = new TextBox(); myText.Location = new Point(25,25); this.Controls.Add (myText); }
18
5.3 Windows控件使用 5.3.1常用控件和属性 表5.3列出了常用的Windows 窗体控件。 表5.3 常用Windows控件
19
5.3.1常用控件和属性 控件都有很多属性,并且大多数控件的属性都派生于System.Windows.Forms.Control 类,所以它们都有一些共同的属性。见表5.4所示。 表5.4 Control类的常见属性
20
5.3.1常用控件和属性 控件对用户或应用程序的某些行为做出相应的响应,这些行为称做事件。Control类的常见事件如表5.5所示:
21
5.3.2 Label 控件和LinkLabel 控件 Windows 窗体 Label 控件用于显示用户不能编辑的文本或图像。
Label 控件也可以用来为其他控件定义访问键。在标签 (Label) 控件中定义访问键时,用户可以按 ALT 键和指定字符将焦点移动到 Tab 键顺序中的下一个控件上。因为标签无法接收焦点,所以焦点自动移动到Tab键顺序中的下一个控件上。 标签中显示的标题包含在 Text 属性中,文本在标签内的对齐方式可以通过Alignment 属性设置。
22
5.3.2 Label 控件和LinkLabel 控件 【例5.3】向带标签的控件分配访问键。
打开项目和窗体,先建立一个标签,然后按任意顺序绘制控件,并将该标签的 TabIndex 属性设置为比另一个控件小 1。将该标签的 UseMnemonic 属性设置为 true。在该标签的 Text 属性中使用“and”符 (&) 为该标签分配访问键。 例如: label1.UseMnemonic = true; label1.Text = "&Print"; label2.UseMnemonic = true; label2.Text = "&Copy && Paste";
23
5.3.2 Label 控件和LinkLabel 控件 【例5.4】使用 LinkLabel 控件链接到另一个窗体。
将 Text 属性设置为“打开另一窗体”。设置 LinkArea 属性,将标题的全部指示为链接,指示的方式取决于该链接标签与外观相关的属性,这里使用默认值。 在 LinkClicked 事件处理程序中,调用Show方法以打开项目中的另一个窗体,并将 LinkVisited属性设置为true。如图5.6所示。 protected void LinkLabel1_LinkClicked(object sender, System.EventArgs e) { // 显示另一个窗口. Form f2 = new Form(); f2.Show(); linkLabel1.LinkVisited = true; } 图5.6 链接到另一个窗体
24
5.3.2 Label 控件和LinkLabel 控件 【例5.5】使用LinkLabel控件启动Internet Explorer并链接到Web页。 将Text属性设置为适当的标题。设置LinkArea属性以确定将标题的哪一部分指示为链接。 在 LinkClicked 事件处理程序中,将LinkVisited属性设置为true,并使用 Process.Start方法以某个URL启动默认浏览器。若要使用Process.Start方法,需要向 System.Diagnostics 命名空间添加一个引用。 例如: protected void LinkLabel1_LinkClicked(object sender, System.EventArgs e) { //通过设置LinkVisited属性为真来改变连接文本的颜色 linkLabel1.LinkVisited = true; // 调用Process.Start方法来通过一个URL打开默认的浏览器 System.Diagnostics.Process.Start(" }
25
5.3.3 Button 控件 Windows窗体Button控件允许用户通过单击来执行操作。每当用户单击按钮时,即调用Click事件处理程序。可将代码放入Click事件处理程序来执行所需要的操作。 在任何Windows窗体上都可以指定某个Button 控件为接受按钮(也称作默认按钮)。每当用户按 ENTER 键时,即单击默认按钮,而不管当前窗体上其他哪个控件具有焦点。在设计器中指定接受按钮的方法是:选择按钮所驻留的窗体,在“属性”窗口中将窗体的AcceptButton属性设置为Button控件的名称。也可以以编程方式指定接受按钮,在代码中将窗体的 AcceptButton 属性设置为适当的 Button 控件。 例如: private void SetDefault(Button myDefaultBtn) { this.AcceptButton = myDefaultBtn; }
26
5.3.3 Button 控件 在任何 Windows 窗体上都可以指定某个 Button 控件为取消按钮。每当用户按 ESC 键时,即单击取消按钮,而不管窗体上的其他哪个控件具有焦点。通常设计这样的按钮可以允许用户快速退出操作而无须执行任何动作。 在设计器中指定取消按钮方法:选择按钮所驻留的窗体后,在“属性”窗口中,将窗体的CancelButton 属性设置为 Button 控件的名称。也可以以编程方式指定取消按钮,将窗体的 CancelButton 属性设置为适当的 Button 控件。例如: private void SetCancelButton(Button myCancelBtn) { this.CancelButton = myCancelBtn; } Windows窗体Button 控件的最基本用法是在单击按钮时运行某些代码。例如: private void button1_Click(object sender, System.EventArgs e) MessageBox.Show("button1 was clicked");
27
5.3.3 Button 控件 Button控件最常用的事件是Click,单击 Button 控件还生成许多其他事件,如 MouseEnter、MouseDown 和 MouseUp 事件。 Button控件不支持双击事件,如果用户尝试双击 Button 控件,将分别以单击单独处理。
28
5.3.4 TextBox 控件 Windows 窗体文本框用于获取用户输入或显示文本。TextBox 控件通常用于可编辑文本,不过也可使其成为只读控件。文本框可以显示多个行,这时它对文本换行使其符合控件的大小。TextBox 控件只能对显示或输入的文本提供单个格式化样式。若要显示多种类型的带格式文本,可以使用 RichTextBox 控件。 控件显示的文本包含在 Text 属性中。默认情况下,最多可在一个文本框中输入 2048 个字符。如果将 MultiLine 属性设置为 true,则最多可输入 32 KB 的文本。Text 属性可以在设计时使用“属性”窗口设置,也可在运行时用代码设置,或者在运行时通过用户输入来设置。在运行时通过读取 Text 属性来得到文本框的当前内容。
29
5.3.4 TextBox 控件 下面的代码在运行时设置控件中的文本。 private void InitializeMyControl()
{ // 初始化把文本放入控件中. textBox1.Text = "This is a TextBox control."; } InitializeMyControl 过程不会自动执行,而需进行调用。 文本框控件最常用的事件是TextChanged事件。当文本框的内容发生变化的时候就触发这个事件。
30
5.3.4 TextBox 控件 TextBox控件应用很广,下面分别说明。
当 Windows 窗体 TextBox 控件最初收到焦点时,文本框内的默认插入位置是在任何现有文本的左边。用户可以使用键盘或鼠标来移动插入点。如果文本框失去焦点而后又再次获得焦点,则插入点为用户上一次放置的位置。 将 SelectionStart 属性设置为适当值。如果值为零,则插入点紧挨第一个字符的左边。将 SelectionLength 属性设置要选择的文本的长度。 下面的代码总是将插入点返回到 0。当然必须将 TextBox1_Enter 事件处理程序绑定到该控件。 private void textBox1_Enter(Object sender, System.EventArgs e) { textBox1.SelectionStart = 0; textBox1.SelectionLength = 0; }
31
5.3.4 TextBox 控件 密码框是一种 Windows 窗体文本框,它在用户键入字符串时显示占位符。
● 创建密码文本框 密码框是一种 Windows 窗体文本框,它在用户键入字符串时显示占位符。 将TextBox 控件的 PasswordChar 属性设置为某个特定字符。PasswordChar属性指定在文本框中显示的字符。例如,如果希望在密码框中显示星号,则请在“属性”窗口中将PasswordChar属性指定为 “*”。运行时,无论用户在文本框中键入什么字符,都显示为星号。 下面的代码将初始化一个文本框,此文本框接受最长可达 14 个字符的字符串,并显示星号来替代字符串。 private void InitializeMyControl() { // 设置文本内容为空. textBox1.Text = ""; //密码框的字符设为“*” textBox1.PasswordChar = '*'; // 控件不允许超过14个字符. textBox1.MaxLength = 14; }
32
5.3.4 TextBox 控件 ● 以编程方式选择文本 在 Windows 窗体 TextBox 控件中,可以以编程方式选择文本。例如,如果创建一个可在文本中搜索特定字符串的函数,就可以选择那些文本,将找到的字符串的位置醒目地通报给读者。 将 SelectionStart 属性设置为要选择的文本的开始位置。SelectionStart 属性是一个数字,指示文本字符串内的插入点,值为 0 表示最左边的位置。如果将 SelectionStart 属性设置为等于或大于文本框内的字符数的值,则插入点被放在最后一个字符后。 将 SelectionLength 属性设置为要选择的文本的长度。SelectionLength 属性是一个设置插入点宽度的数值。如果将 SelectionLength 设置为大于0 的数,则会选择该数目的字符,开始位置是当前插入点。 通过 SelectedText 属性访问选定的文本。
33
5.3.4 TextBox 控件 下面的代码将在控件的 Enter 事件发生时选择文本框的内容。必须将 TextBox1_Enter 事件处理程序绑定到控件。 private void textBox1_Enter(object sender,System.EventArgs e) { textBox1.SelectionStart = 0; textBox1.SelectionLength = textBox1.Text.Length; } 文本框控件还提供了一些方法,方便用户使用。 Clear:清除文本框中的文本 AppendText:向文本框里添加文字 Copy:复制文本框的文本到剪贴板 Cut:剪切文本框文本到剪贴板 Paste:用剪贴板内容替换文本框文本 Select:在文本框中选择指定范围的文本 SelectAll:选择文本框所有内容 下面给出TextBox的应用示例。
34
5.3.4 TextBox 控件 【例5.6】创建一个带垂直滚动条的多行 TextBox 控件。
private void CreateMyMultilineTextBox() { // 创建一个TextBox控件 TextBox textBox1 = new TextBox(); // 设置为多行 textBox1.Multiline = true; // 添加滚动 textBox1.ScrollBars = ScrollBars.Vertical; //允许换行 textBox1.AcceptsReturn = true; // 允许使用Tab键 textBox1.AcceptsTab = true; textBox1.WordWrap = true; // 设置初始值 textBox1.Text = "Welcome!"; }
35
【例5.6】 运行结果如图5.7所示。 图5.7 运行结果
36
5.3.5 RadioButton控件 RadioButton控件旨在为用户提供两种或多种设置以便选择其一。
当单击 RadioButton 控件时,其 Checked 属性设置为 true,并且调用 Click 事件处理程序。当 Checked 属性的值更改时,将引发 CheckedChanged 事件。如果 AutoCheck 属性设置为 true(默认),则当选择单选按钮时,将自动清除该组中的所有其他单选按钮。通常仅当使用验证代码以确保选定的单选按钮是允许的选项时,才将该属性设置为 false。用 Text 属性设置控件内显示的文本,该属性可以包含访问键快捷方式。访问键允许用户通过同时按 ALT 键和访问键来“单击”控件。 如果将 Appearance 属性设置为Appearance.Button,则RadioButton控件的外观可以像命令按钮一样。当选定它时,它看似已被按下。单选按钮还可以使用Image和ImageList属性显示图像。 在一个容器(如Panel控件、GroupBox 控件或窗体)内绘制单选按钮即可将它们分组。直接添加到一个窗体中的所有单选按钮将形成一个组。若要添加不同的组,必须将它们放到面板或分组框中。 将RadioButton控件分组使之独立于其他组工作。具体做法是:将GroupBox控件或Panel控件从“工具箱”的“Windows 窗体”选项卡拖到窗体上。 然后在GroupBox控件或Panel控件上绘制RadioButton控件即可。
37
5.3.5 RadioButton控件 下面的代码创建和初始化一个 RadioButton,并为其赋予切换按钮的外观,同时将它的 AutoCheck 属性设置为 false,然后将它添加到 Form 中。例如: private void InitializeMyRadioButton() { //创建一个 RadioButton. RadioButton radioButton1 = new RadioButton(); radioButton1.Appearance = Appearance.Button; // 选中时不传值 radioButton1.AutoCheck = false; // 把RadioButton放入窗体中 Controls.Add(radioButton1);}
38
5.3.6 CheckBox控件 Windows 窗体复选框 (CheckBox)虽然和单选按钮复选框看似功能类似,却存在重要差异:当用户选择某单选按钮时,同一组中的其他单选按钮不能同时选定。相反,却可以选择任意数目的复选框。 Windows 窗体 CheckBox 控件常用于为用户提供是/否或真/假选项。可以成组使用复选框 (CheckBox) 控件以显示多重选项,用户可以从中选择一项或多项。多个复选框可以使用GroupBox 控件进行分组。这对于可视外观以及用户界面设计很有用,因为成组控件可以在窗体设计器上一起移动。 CheckBox 控件有两个重要属性 Checked 和 CheckState。Checked 属性返回 true 或 false。CheckState 属性返回 CheckState.Checked(选择) 或CheckState.Unchecked(未选择);或者,如果 ThreeState 属性设置为 true,CheckState 还可能返回 CheckState.Indeterminate(不确定状态)。在不确定状态,复选框以浅灰色显示,以表示该选项不可用。 每当用户单击某 Windows 窗体 CheckBox 控件时,便发生 Click 事件。可以编写应用程序以根据复选框的状态执行某些操作。
39
5.3.6 CheckBox控件 在Click事件处理程序中,使用Checked属性确定控件的状态,以执行任何必要操作。
private void checkBox1_Click(object sender, System.EventArgs e) { // 复选框控件的文本属性在每次控件被单击的时候都会改变,表明被选择或 者不被选择. if (checkBox1.Checked) checkBox1.Text = "Checked"; } else checkBox1.Text = "Unchecked";
40
5.3.6 CheckBox控件 使用 case 语句查询 CheckState 属性的值以确定操作的进程。当 ThreeState 属性设置为 true 时,CheckState 属性可以返回三个可能值,表示该复选框已选中、未选中或第三种不确定状态 private void checkBox1_Click(object sender, System.EventArgs e) { switch(checkBox1.CheckState) case CheckState.Checked: // 被选择状态 case CheckState.Unchecked: // 未选择状态 case CheckState.Indeterminate: // 不确定状态. } 注意 当 ThreeState 属性设置为 true 时,Checked 属性对 CheckState.Che cked 和 CheckState.Indeterminate 均返回 true。
41
5.3.6 CheckBox控件 下面的代码检查 Checked 属性的值以确定其状态,并设置选项。
private void SetOptions() { // 创建一个新的对象并且根据两个复选框控件的值设置它的属性// 你必须 为”myobject”设置一个合适的对象类型 MyObject myObj = new MyObject(); // 假设对象有个叫作"Property1" and "Property2."的属性 myObj.Property1 = CheckBox1.Checked; myObj.Property2 = CheckBox2.Checked; }
42
5.3.7 ListBox控件 ListBox 控件用于显示列表项,用户可从中选择一项或多项。如果总项数超出可以显示的项数,则自动向ListBox控件添加滚动条。当 MultiColumn 属性设置为 true 时,列表框以多列形式项,并且会出现一个水平滚动条。当 MultiColumn 属性设置为 false 时,列表框以单列形式显示,并且会出现一个垂直滚动条。当ScrollAlwaysVisible设置为true时,无论项数多少都将显示滚动条。SelectionMode属性确定一次可以选择多少列表项。 SelectedIndex 属性返回对应于列表框中第一个选定项的整数值。通过在代码中更改 SelectedIndex 值,可以编程方式更改选定项。如果未选定任何项,则SelectedIndex值为 -1。如果选定了列表中的第一项,则 SelectedIndex 值为 0。当选定多项时,SelectedIndex值反映列表中最先出现的选定项。SelectedItem 属性类似于 SelectedIndex,但它返回项本身,通常是字符串值。Items.Count 属性反映列表中的项数,并且Items.Count属性的值总比SelectedIndex的最大可能值大1,因为SelectedIndex是从零开始的。 若要在 ListBox 控件中添加或删除项,可使用 Items.AddItems.Insert、Items.Clear 或 Items.Remove 方法。或者在设计时使用Items属性向列表添加项。
43
5.3.7 ListBox控件 【例5.7】创建一个 ListBox 控件,在该控件的多列中显示多个项,并且在控件列表中能够选定多个项。
设计窗体Form1,在窗体中加入命令按钮Button1,在Button1单击事件中加入如下代码: private void button1_Click(object sender, System.EventArgs e) { // 创建一个ListBox. ListBox listBox1 = new ListBox(); // 设置大小和位置 listBox1.Size = new System.Drawing.Size(200, 100); listBox1.Location = new System.Drawing.Point(10,10); this.Controls.Add(listBox1); // 显示多行 listBox1.MultiColumn = true; // 设置可多行选择 listBox1.SelectionMode = SelectionMode.MultiExtended; listBox1.BeginUpdate(); for (int x = 1; x <= 50; x++)
44
【例5.7】 { listBox1.Items.Add("Item " + x.ToString()); }
listBox1.EndUpdate(); // 选择ListBox中的三项 listBox1.SetSelected(1, true); listBox1.SetSelected(3, true); listBox1.SetSelected(5, true); // 在控制台上显示选中的第一项与第二项 System.Diagnostics.Debug.WriteLine(listBox1.SelectedItems[1].ToString()); System.Diagnostics.Debug.WriteLine(listBox1.SelectedIndices[0].ToString());
45
【例5.7】 运行结果如图5.8所示。 图5.8 运行结果
46
5.3.8 ComboBox控件 ComboBox 控件用于在下拉组合框中显示数据。默认情况下,ComboBox 控件分两个部分显示:顶部是一个允许用户键入列表项的文本框。第二个部分是列表框,它显示用户可以从中进行选择的项的列表。 SelectedIndex 属性返回一个整数值,该值与选定的列表项相对应。通过在代码中更改 SelectedIndex 值,可以编程方式更改选定项;列表中的相应项将出现在组合框的文本框部分。如果未选定任何项,则 SelectedIndex 值为 -1。如果选定列表中的第一项,则 SelectedIndex 值为 0。SelectedItem 属性与 SelectedIndex 类似,但它返回项本身,通常是一个字符串值。Items.Count 属性反映列表中的项数,并且 Items.Count 属性的值总比 SelectedIndex 的最大可能值大 1,因为 SelectedIndex 是从零开始的。 若要在 ListBox 控件中添加或删除项,可以使用 Items.Add、Items.Insert、Items.Clear 或 Items.Remove 方法。或者,可以在设计器中使用 Items 属性向列表添加项。
47
5.3.8 ComboBox控件 【例5.8】综合应用,实现的功能是:在文本框中输入字符,点击“添加”向 ComboBox 添加项;在文本框中输入字符,点击“查找”查询 ComboBox 中的项;点击“添加1000个项”向ComboBox中添加1000个数据项;点击“被选择的项是:”,弹出对话框,显示选择的项。 代码如下: using System; using System.Windows.Forms; namespace Win32Form1Namespace { public class Win32Form1 : System.Windows.Forms.Form private System.Windows.Forms.Button addButton; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Button addGrandButton; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Button showSelectedButton; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button findButton;
48
【例5.8】 private System.Windows.Forms.Label label1; public Win32Form1()
{ this.InitializeComponent(); } [System.STAThreadAttribute()] public static void Main() System.Windows.Forms.Application.Run(new Win32Form1()); private void InitializeComponent() this.addButton = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); this.addGrandButton = new System.Windows.Forms.Button(); this.comboBox1 = new System.Windows.Forms.ComboBox();
49
【例5.8】 this.showSelectedButton = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox(); this.findButton = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.addButton.Location = new System.Drawing.Point(248, 32); this.addButton.Size = new System.Drawing.Size(40, 24); this.addButton.TabIndex = 1; this.addButton.Text = "添加"; this.addButton.Click += new System.EventHandler(this.addButton_Click); this.textBox2.Location = new System.Drawing.Point(8, 64); this.textBox2.Size = new System.Drawing.Size(232, 20); this.textBox2.TabIndex = 6; this.textBox2.Text = ""; this.addGrandButton.Location = new System.Drawing.Point(8, 96); this.addGrandButton.Size = new System.Drawing.Size(280, 23); this.addGrandButton.TabIndex = 2;
50
【例5.8】 this.addGrandButton.Text = "添加1000个项";
this.addGrandButton.Click += new System.EventHandler(this.addGrand Button_Click); this.comboBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)| System.Windows.Forms.AnchorStyles.Right); this.comboBox1.DropDownWidth = 280; this.comboBox1.Items.AddRange(new object[] {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}); this.comboBox1.Location = new System.Drawing.Point(8, 248); this.comboBox1.Size = new System.Drawing.Size(280, 21); this.comboBox1.TabIndex = 7; this.showSelectedButton.Location = new System.Drawing.Point(8, 128); this.showSelectedButton.Size = new System.Drawing.Size(280, 24); this.showSelectedButton.TabIndex = 4; this.showSelectedButton.Text = "被选择的项是:";
51
【例5.8】 this.showSelectedButton.Click += new System.EventHandler(this.show SelectedButton_Click); this.textBox1.Location = new System.Drawing.Point(8, 32); this.textBox1.Size = new System.Drawing.Size(232, 20); this.textBox1.TabIndex = 5; this.textBox1.Text = ""; this.findButton.Location = new System.Drawing.Point(248, 64); this.findButton.Size = new System.Drawing.Size(40, 24); this.findButton.TabIndex = 3; this.findButton.Text = "查找"; this.findButton.Click += new System.EventHandler(this.findButton_Click); this.label1.Location = new System.Drawing.Point(8, 224); this.label1.Size = new System.Drawing.Size(144, 23); this.label1.TabIndex = 0; this.label1.Text = " ComboBox中的项:"; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 273); this.Controls.AddRange(new System.Windows.Forms.Control[] {this.comboBox1,
52
【例5.8】 this.textBox2, this.textBox1, this.showSelectedButton,
this.findButton, this.addGrandButton, this.addButton, this.label1}); this.Text = "ComboBox Sample"; } private void addButton_Click(object sender, System.EventArgs e) { comboBox1.Items.Add(textBox1.Text); private void addGrandButton_Click(object sender, System.EventArgs e) comboBox1.BeginUpdate(); for (int i = 0; i < 1000; i++)
53
【例5.8】 { comboBox1.Items.Add("Item 1" + i.ToString()); }
comboBox1.EndUpdate(); private void findButton_Click(object sender, System.EventArgs e) int index = comboBox1.FindString(textBox2.Text); comboBox1.SelectedIndex = index; private void showSelectedButton_Click(object sender, System.EventArgs e) int selectedIndex = comboBox1.SelectedIndex; Object selectedItem = comboBox1.SelectedItem; MessageBox.Show("Selected Item Text: " + selectedItem.ToString() + "\n" +"Index: " + selectedIndex.ToString());
54
【例5.8】 运行结果如图5.9所示。 图5.9 运行结果
55
5.3.9 GroupBox控件 GroupBox(分组框)控件用于为其他控件提供组合容器。GroupBox 控件类似于 Panel 控件,但GroupBox 控件可以显示标题,而Panel 控件有滚动条。设计时当移动单个 GroupBox 控件时,它包含的所有控件也将一起移动。 如果要把已有控件放到分组框中,可以选择所有这些控件,将它们剪切到剪贴板,选择 GroupBox 控件,然后将它们粘贴到分组框中。也可以将它们拖到分组框中。最后将分组框的Text属性设置为适当标题。 【例5.9】创建一个 GroupBox 和两个 RadioButton 控件。向分组框中添加单选按钮,并将该分组框添加到 Form 中。 private void InitializeMyGroupBox() { // 创建一个 GroupBox 和两个 RadioButton GroupBox groupBox1 = new GroupBox(); RadioButton radioButton1 = new RadioButton(); RadioButton radioButton2 = new RadioButton(); // 设置 GroupBox的样式 groupBox1.FlatStyle = FlatStyle.System;
56
【例5.9】 //添加 RadioButtons 到 GroupBox.
groupBox1.Controls.Add(radioButton1); groupBox1.Controls.Add(radioButton2); // 添加GroupBox 到窗体 Controls.Add(groupBox1); } 运行结果如图5.10所示。 图5.10 运行结果
57
ListView控件 ListView 控件显示带图标的项列表,通过它可创建类似于 Windows 资源管理器右窗格的用户界面。该控件具有4种视图模式:“LargeIcon”、“SmallIcon”、“List”和“Details”。 视图模式由View 属性设置。LargeIcon视图模式在项文本旁显示大图标。如果控件足够大,则项显示在多列中。SmallIcon视图模式除显示小图标外,其他方面与大图标视图模式相同。List视图模式显示小图标,但总是显示在单列中。Details视图模式在多列中显示项。所有视图模式都可显示图像列表中的图像。 Items属性包含控件所显示的项,SelectedItems 属性包含控件中当前选定项的集合。如果将 MultiSelect 属性设置为 true,则用户可选择多项。例如,同时将若干项拖放到另一个控件中。如果 CheckBoxes 属性设置为 true,则 ListView 控件可在项的旁边显示复选框。Activation 属性确定采取何种操作激活列表中的项,选项为“Standard”、“OneClick”和“TwoClick”。“OneClick”方式采用单击激活列表项;“TwoClick”方式采用双击激活列表项;单击更改项文本的颜色。“Standard”方式采用双击激活列表项,但项的外观并不改变。
58
5.3.10 ListView控件 ListView 控件可在设计和运行时添加或移除列表项。 在设计器中添加或移除项
在“属性”窗口中,单击 Items 属性旁的省略号按钮 (……)。出现“ListViewItem 集合编辑器”。要添加项,单击“添加”按钮,然后设置新项的属性,如 Text 和 ImageIndex 属性。若要移除某项,选择该项并单击“移除”按钮。 ● 以编程方式添加项 以编程方式添加项,使用 Items 属性的 Add 方法。 例如: listView1.Items.Add("List item text", 3); ● 以编程方式移除项 以编程方式移除项,使用 Items 属性的 RemoveAt 或 Clear 方法。RemoveAt 方法移除一个项,而 Clear 方法移除列表中的所有项。 // 移除列表的第一项 listView1.Items.RemoveAt(0); // 清除所有项 listView1.Items.Clear();
59
ListView控件 ● 在设计器中添加列 将控件的 View 属性设置为“Details“。在“属性”窗口中,单击 Columns 属性旁的省略号按钮,出现“ColumnHeader 集合编辑器”。使用“添加”按钮添加新列。然后可以选择列标头并设置其文本(列的标题)、文本对齐方式和宽度。如图5.11所示。 图5.11 ColumnHeader 集合编辑器
60
ListView控件 ● 以编程方式添加列 将控件的 View 属性设置为“Details”,使用列表视图的 Columns 属性的 Add 方法。例如: // 将View设为Details listView1.View = View.Details; // 添加一宽20左对齐的列 listView1.Columns.Add("File type", 20, HorizontalAlignment.Left); ● 在列表视图中显示图像 Windows 窗体 ListView 控件可显示3个图像列表中的图标。List视图、Details视图和SmallIcon视图显示SmallImageList 属性中指定的图像列表中的图像。LargeIcon视图显示LargeImageList 属性中指定的图像列表中的图像。列表视图还能在大图标或小图标旁显示在 StateImageList 属性中设置的一组附加图标。 将SmallImageList、LargeImageList 或 StateImageList 设置为已有 ImageList 组件。可在设计器中使用“属性“窗口设置,也可在代码中设置。例如: listView1.SmallImageList = imageList1; 为每个具有关联图标的列表项设置 ImageIndex 或 StateImageIndex 属性。这些属性可通过“ListViewItem 集合编辑器”设置。要打开“ListViewItem 集合编辑器”,请单击“属性”窗口中 Items 属性旁的省略号(…)按钮。也可用代码进行设置,例如: // 设置第一列表项显示第四幅图像 listView1.Items[0].ImageIndex = 3;
61
PictureBox控件 Windows 窗体 PictureBox 控件用于显示位图、GIF、JPEG、图元文件或图标格式的图形。显示的图片由 Image 属性确定,SizeMode 属性控制图像和控件彼此适合的方式。 可显示的文件类型如表5.6所示。 表5.6 图形文件类型 PictureBox 控件该属性可在设计时或运行时采用代码设置。 ● 在设计时显示图片 在窗体上绘制 PictureBox 控件。在“属性”窗口中选择 Image 属性,然后单击省略号按钮以显示“打开”对话框。如果要查找特定文件类型(例如 .gif 文件),在“文件类型”框中选择该类型,然后选择要显示的文件即可。
62
5.3.11 PictureBox控件 在“属性”窗口中,选择 Image 属性,并右击出现在图像对象名称左边的小缩略图图像。选择“重置”。
● 在设计时清除图片 在“属性”窗口中,选择 Image 属性,并右击出现在图像对象名称左边的小缩略图图像。选择“重置”。 PictureBox 控件通过SizeMode 属性选择显示下列方式: (1) 将图片的左上角与控件的左上角对齐 (2) 使图片在控件内居中 (3) 调整控件的大小以适合其显示的图片 (4) 拉伸所显示的图片以适合控件 拉伸图片(尤其是位图格式的图片)可能导致图像质量受损。图元文件(运行时绘制图像的图形指令列表)比位图更适合于拉伸图片。 设置SizeMode属性为 Normal(默认)、AutoSize、CenterImage 或 StretchImage。Normal 表示图像放置在控件的左上角,如果图像大于控件,则剪裁图像的右下边缘。CenterImage 表示图像在控件内居中,如果图像大于控件,则剪裁图片的外边缘。AutoSize 表示将控件的大小调整为图像的大小。StretchImage 则相反,表示将图像的大小调整到控件的大小。
63
在设计时清除图片 private void StretchPic() { //如果需要,改变一个有效的bit图像的路径
string path // 调整图像以适应控件 PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; // 加载图像到控件中 PictureBox1.Image = Image.FromFile(path); }
64
StatusBar控件 Windows 窗体的状态栏通常显示在窗口的底部,应用程序可通过StatusBar 控件在该区域中显示各种状态信息。StatusBar 控件上可以有状态栏面板,用以显示指示状态的文本或图标,或一系列指示进程正在执行的动画图标(如 Microsoft Word 指示正在保存文档)。例如:在鼠标滚动到超级链接时,Internet Explorer 使用状态栏指示某个页面的 URL。Microsoft Word 使用状态栏提供有关页位置、节位置和编辑模式(如改写和修订跟踪)的信息。Visual Studio 使用状态栏提供区分上下文的信息,如告诉如何操纵可停靠的窗口,使其停靠或浮动。 通过将 ShowPanels 属性设置为 false(默认值)并将状态栏的 Text 属性设置为希望出现在状态栏中的文本,可在状态栏中显示一个消息。通过将 ShowPanels 属性设置为 true 并使用 StatusBarPanelCollection 类的 Add 方法,可将状态栏分割为多个面板以显示一种以上类型的信息。 StatusBar 控件内的可编程区域由 StatusBarPanel 类的实例组成。添加这些实例的方式是:在设计时通过 StatusBarPanel 集合编辑器,在运行时通过向 StatusBarPanelCollection 类进行添加。
65
图5.12 StatusBarPanel 集合编辑器
【例5.10】在设计时向状态栏添加面板。 向窗体添加 StatusBar 控件。在“属性”窗口中,通过单击“面板”属性来选择该属性。然后单击“省略号”按钮,打开“StatusBarPanel 集合编辑器”,如图5.12所示。 图5.12 StatusBarPanel 集合编辑器
66
【例5.10】 使用“添加”和“移除”按钮分别向 StatusBar 控件添加面板和从中移除面板。在右侧窗格中出现的属性窗口中配置单个面板的属性。要考虑的重要属性如表5.7所示。 表5.7 状态栏属性
67
5.3.13 Timer控件 时钟(Timer)控件可以按照用户指定的时间间隔来触发事件。常用的属性有2个:
Enabled属性。用来指定时钟是否处于运行状态,也就是说是否可以触发事件。默认值为 False。 InterVal属性。用来指定时钟控件触发时间的时间间隔,单位为毫秒。 时钟控件包括一个Tick事件。当时钟处于运行状态时,每当到达指定时间间隔,就会触发这个事件。 【例5.11】实现简单的间隔计时器,该计时器每五秒钟发一次警报。 public class Class1 { static System.Windows.Forms.Timer myTimer = newSystem.Windows. Forms.Timer(); static int alarmCounter = 1; static bool exitFlag = false; // 当Timer控件激活时执行此函数 private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
68
【例5.11】 private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs) { myTimer.Stop(); //显示一个对话框询问是否继续计时 if(MessageBox.Show("Continue running?", "Count is: " + alarmCounter, MessageBoxButtons.YesNo) == DialogResult.Yes) alarmCounter +=1; myTimer.Enabled = true; } else //停止计时 exitFlag = true;
69
【例5.11】 public static int Main() {
myTimer.Tick += new EventHandler(TimerEventProcessor); //设置计时时间为5秒 myTimer.Interval = 5000; myTimer.Start(); while(exitFlag == false) Application.DoEvents(); } return 0; }
70
5.4 菜单 应用程序可以为不同的上下文(或不同的应用程序状态)显示不同的菜单。可能会有多个 MainMenu 对象,每个对象向用户显示不同的菜单选项。通过包含多个 MainMenu 对象,可以处理用户与应用程序交互时应用程序的不同状态。 应用程序首次打开而没有文件或数据可供用户交互的情况创建一个菜单结构,只具有包含“新建”、“打开”和“退出”命令的传统“文件”菜单。这些菜单项以加载了数据或文件的应用程序为目标。当用户选择“新建”或“打开”菜单项时,它将触发应用程序状态的变化。此时将显示第2个菜单结构,它包含附加菜单项(“关闭”和“保存”)。为了便于演示,在以下示例中,消息框将作为可视化辅助工具来显示。
71
5.4.1 在设计时创建菜单 在“Windows 窗体设计器”中打开需要菜单的窗体。在“工具箱”中双击 MainMenu 组件。即向窗体(显示文本“请在此处输入”)添加了一个菜单,并且 MainMenu 组件添加到了组件栏,如图5.13所示。 图5.13 向窗体添加一个菜单
72
5.4.1 在设计时创建菜单 在菜单设计器中,创建一个顶级菜单项,并将其 Text 属性设置为 &File,然后依次创建3个子菜单,并将它们的 Text 属性分别设置为 &New、&Open 和 E&xit。 在“Windows 窗体设计器”中,单击窗体(Form1.vb 或 Form1.cs)使之成为焦点。在“属性”窗口中,确保“菜单”属性已设置为刚创建的菜单。 为“新建”和“打开”菜单项创建一个名为 MenuSelect 的多路广播事件处理程序。它之所以是多路广播事件处理程序,是因为它将为两个菜单项处理 Click 事件。 在 MenuSelect 事件处理程序中输入以下代码: private void MenuSelect(object sender, System.EventArgs e) { MessageBox.Show("A file has been opened.", "Instead of a new file, here's a message box."); LoadSecondMenu(); } 按 F5 键运行,调试该应用程序。
73
5.4.1 在设计时创建菜单 此窗体有一个菜单“File”,该菜单包含“文件”、“新建”、“打开”和“退出”菜单项。单击“新建”或“打开”引发事件,该事件由 MenuSelect 事件处理程序处理。该方法显示一个消息框并更改应用程序状态。应用程序状态的更改是通过添加两个菜单项“关闭”和“保存”来指示的,如图5.14所示。 图5.14 消息框显示更改应用程序状态
74
5.4.2 以编程方式创建菜单 下面使用代码设计一个与上例相同的切换菜单结构的 Windows 应用程序。
以下示例具有一个 MainMenu 对象,用于首次打开应用程序。它只具有一个包含“新建”、“打开”和“退出”命令的传统“文件”菜单。使用一个重载的 Add 方法创建菜单项并将其与事件处理程序相关联。通过动态连接事件处理程序,可以方便地用信号通知应用程序,单击“新建”或“打开”菜单命令应该触发应用程序状态的变化。 // 创建一个主菜单对象和一个菜单项对象. MainMenu mmAppStart; MenuItem miFile;public void AppStartMenu() { // 创建一个主菜单对象的实例. mmAppStart = new MainMenu(); //创建一个顶层的菜单项和两个菜单项 // 使用这个重载的方法在随后调用一个事件处理方法MenuSelect // 你可以通过菜单的选择来改变应用程序的状态
75
5.4.2 以编程方式创建菜单 miFile = new MenuItem("&File", new EventHandler(MenuSelect)); miFile.MenuItems.Add("&New", new EventHandler(MenuSelect)); miFile.MenuItems.Add("&Open", new EventHandler(MenuSelect)); miFile.MenuItems.Add("&Exit"); // 添加一个顶层的菜单项到MainMenu的组件中 // 并把MainMenu组件设为窗体的菜单 mmAppStart.MenuItems.Add(miFile); // 设置窗体的菜单为刚创建的菜单. this.Menu = mmAppStart; }
76
5.4.2 以编程方式创建菜单 在第2个方法中,用对应于第2个应用程序状态的 MenuItems ,创建 MainMenu 组件的第2个实例。例如,当用户打开文件后,可以加入将其关闭和保存的命令。复制原菜单结构,以用作此菜单结构的基础,并保留“文件”、“新建”、“打开”和“退出”菜单项。 // 创建第二个窗体对象. private MainMenu mmFileLoadedMenu; private void FileLoadedMenu() { mmFileLoadedMenu = new MainMenu(); // 通过方法CloneMenu 来复制第一个菜单. mmFileLoadedMenu.MenuItems.Add(miFile.CloneMenu()); // 创建另外的两个有新的关于应用程序状态的菜单项. MenuItem mnuitemClose = new MenuItem("&Close"); MenuItem mnuitemSave = new MenuItem("&Save");
77
5.4.2 以编程方式创建菜单 //添加两个菜单项到上面复制的菜单里 // 利用Add方法通过它们的索引值来初始化它们的顺序.
mmFileLoadedMenu.MenuItems[0].MenuItems.Add(2, mnuitemClose); mmFileLoadedMenu.MenuItems[0].MenuItems.Add(3, mnuitemSave); // 配置刚创建的菜单到窗体中. Menu = mmFileLoadedMenu; }
78
5.4.2 以编程方式创建菜单 将一行代码添加到 Form1 调用构造函数的 InitializeComponent 方法后面,以调用先前创建的 AppStartMenu 方法:AppStartMenu(); 在该类中创建一个事件处理程序,用以将窗体的菜单属性切换到 FileLoadedMenu。 以下代码没有加载文件,而是打开一个消息框来指示应用程序状态的变化。 protected void MenuSelect(Object sender, System.EventArgs e) { MessageBox.Show("A file has been opened.", "Instead of a new file, here's a message box."); FileLoadedMenu(); } 按 F5 键运行,调试该应用程序。 窗体有一个菜单,该菜单包含“文件”、“新建”、“打开”和“退出”菜单项。单击“新建”或“打开” 菜单项, 引发事件。该事件由 MenuSelect 事件处理程序处理,它显示 MessageBox 并更改应用程序状态。应用程序状态的更改是通过添加两个菜单项“关闭”和“保存”来指示的。
79
5.4.2 以编程方式创建菜单 以编程方式向 Windows 窗体添加菜单的时候,在“代码编辑器”中,创建一个新公共方法,其中包含将菜单添加到窗体的代码。在该方法内添加类似于以下内容的代码,以创建 MainMenu 组件的实例: public void AddMenu() { MainMenu mnuFileMenu = new MainMenu(); this.Menu = mnuFileMenu; } 将 MainMenu 组件添加到 Windows 窗体后,需要向其添加菜单项。菜单设计器可在设计时向菜单组件添加菜单项。菜单内容保存在一个集合内,所以可在运行时通过向此集合添加 MenuItem 对象来向菜单添加菜单项。
80
5.4.2 以编程方式创建菜单 ● 编程方式向菜单添加菜单项 如果还没有 MainMenu 组件,则向公共方法内的 Windows 窗体添加一个 MainMenu 组件,并将一个 MainMenu 类的实例分配给该窗体的 Menu 属性。 public void AddMenuAndItems(){MainMenu mnuFileMenu = new MainMenu();this.Menu = mnuFileMenu;} 在该方法内,创建要添加到 MainMenu 对象的集合中的 MenuItem 对象: MenuItem myMenuItemFile = new MenuItem("&File"); MenuItem myMenuItemNew = new MenuItem("&New"); ● 以编程方式移动菜单项 下列代码更改菜单项的索引位置: public void MoveMenuItemDown() { //在MainMenu里向下移动MenuItem1一个位置 Menu.MenuItems[0].MenuItems[0].Index++; }
81
5.4.2 以编程方式创建菜单 禁用菜单项只要在设置菜单项的属性(如Text)的方法将 Enabled 属性设置为 false ,例如:
● 以编程方式禁用菜单项 禁用菜单项只要在设置菜单项的属性(如Text)的方法将 Enabled 属性设置为 false ,例如: menuItem1.Enabled = false; 从菜单删除菜单项就是将该菜单项从相应的 MainMenu(或 MenuItem)对象的 MenuItems 集合中删除。根据应用程序的运行时需要,如果此菜单项以后要再次使用,最好是隐藏该菜单项而不是删除它。 ● 以编程方式删除菜单项 调用 Menu.MenuItemCollection 类的 Remove 方法可以删除菜单项。例如:创建一个包含顶级 MenuItem mnuEuropeNations 的菜单结构,其中有3个菜单项Italy、Germany 和 France。然后删除 MenuItems 中的一个France菜单项。代码如下: private MainMenu mnuCountries; private MenuItem mnuItemEuropeNations; private MenuItem mnuItemItaly; private MenuItem mnuItemGermany; private MenuItem mnuItemFrance;
82
以编程方式删除菜单项 public void CreateNationMenu () { // 创建菜单和菜单项的实例
mnuCountries = new MainMenu(); mnuItemEuropeNations = new MenuItem("Some Nations of E&urope"); mnuItemItaly = new MenuItem("&Italy"); mnuItemGermany = new MenuItem("&Germany"); mnuItemFrance = new MenuItem("&France"); // 添加 mnuItemEuropeNations 到主菜单的菜单集合中 mnuCountries.MenuItems.Add(mnuItemEuropeNations); // 添加子菜单到 mnuItemEuropeNations mnuItemEuropeNations.MenuItems.Add(mnuItemItaly); mnuItemEuropeNations.MenuItems.Add(mnuItemGermany); mnuItemEuropeNations.MenuItems.Add(mnuItemFrance);
83
以编程方式删除菜单项 // 制定窗体菜单mnuCountries Menu = mnuCountries; }
public void RemoveFrance() { mnuItemEuropeNations.MenuItems.Remove(mnuItemFrance);
84
5.5 对话框 对话框就是FormBorderStyle 枚举属性设置为 FixedDialog 的窗体,用于交互和检索信息。可以使用 Windows 窗体设计器构造自己的自定义对话框。通过向对话框添加控件(例如 Label、Textbox 和 Button)来自定义对话框以满足特定需要。对话框通常不包含菜单栏、窗口滚动条、“最小化”和“最大化”按钮、状态栏和可调整边框。 5.5.1 在设计时创建对话框 通过在“解决方案资源管理器”中右击项目,指向“添加”,然后单击“Windows 窗体”,将窗体添加到项目中。右击窗体,选择“重命名”,将窗体“DialogBox.cs”重命名为合适的名称。在“属性”窗口中,将 FormBorderStyle 属性更改为“FixedDialog”。通过设置ControlBox、MinimizeBox 和 MaximizeBox等属性,可以定义窗体的外观。在“代码编辑器”中可以自定义事件方法。 另外,.NET 框架包含许多预格式化的对话框,可实现基本任务(打开文件、打印文件和保存文件)对话框。
85
5.5.1 在设计时创建对话框 【例5.12】单击按钮事件显示对话框,如图5.15所示。
private void button1_Click(object sender, System.EventArgs e) { Form dlg1 = new Form(); dlg1.ShowDialog(); } 图5.15 单击按钮事件显示对话框
86
5.5.2 以编程方式设置属性 设置 DialogResult 属性,键入类似下列的代码:
private void InformationProcessed() { // 这段代码将为一个窗体设置DialogResult属性 DialogResult = DialogResult.Yes; // 或者 // 这段代码将为一个按钮设置DialogResult 属性. button1.DialogResult = DialogResult.No; } 设置 DialogResult 属性将引起对话框自动关闭,为了处理控件的 Click 事件,需要暂停对话框的关闭。要阻止DialogResult 属性关闭对话框,可以在在事件处理程序中,键入类似于下列的代码: private void button1_Click(object sender, System.EventArgs e) DialogResult = DialogResult.None;
87
5.5.2 以编程方式设置属性 下列的代码可以检索 DialogResult 值: private void DisplayDialog()
{ // 创建并一个对话框的实例Form dlg = new Form(); // 显示对话框并为窗体确定DialogResult 属性状态 if (dlg.ShowDialog() == DialogResult.OK ) // 在此处理来自于对话框的数据 } 通常,此代码将放在创建和显示该对话框的代码后面。
88
5.5.2 以编程方式设置属性 下面的代码演示通过对话框中定义的属性公开组合框 (cmbState) 的值:
public string StateSelected { Get return cmbState.Text; } 公开提供的数据的属性后,应用程序可检索对话框数据。例如: private void ShowMyDialog() //创建并显示一个对话框的实例 Form dlg = new Form(); dlg.ShowDialog(); // 确定DialogResult的状态. if (dlg.DialogResult == DialogResult.OK) // 在一个消息框里显示被选择了的对话框的组合框的状态 MessageBox.Show (dlg.StateSelected);
89
5.5.2 以编程方式设置属性 在可检索对话框信息之前,需要创建这样的类对象:该类对象使用对话框类中的属性揭示对话框信息并公开它。下面的示例中创建了一个对话框,该对话框公开一个包含地理坐标信息的属性。于是在对话框关闭后,可通过一个对象获得输入到对话框中的信息。 ● 创建公开数据的对话框 创建一个称为“MapDialog”的 Windows 应用程序,重命名窗体“MapDialog”。 从工具箱中拖出2个 TextBox 控件,在“属性”窗口中,将一个 Textbox 控件的 Name 和 Text 属性设置为 Latitude,另一个 Textbox 控件的 Name 和 Text 属性设置为 Longitude。 从工具箱中拖出2个 Button 控件。将第一个 Button 控件重命名为“确定”,并将 DialogResult 属性设置为“确定”。将第二个 Button 控件重命名为“取消”,并将 DialogResult 属性设置为“取消”。
90
5.5.2 以编程方式设置属性 为 Button 控件的每个 Click 事件创建一个事件处理程序,以关闭窗体。
private void button1_Click(object sender, System.EventArgs e) { this.Close(); } private void button2_Click(object sender, System.EventArgs e)
91
5.5.2 以编程方式设置属性 创建一个属性,将用它来保存对话框的数据:
public MapCoordinates MapCoordinates { Get //创建你的对象的实例 // 在这种情况下,创建一个地图对象存储地图的纬度和经度 MapCoordinates mc = new MapCoordinates(); mc.Latitude = this.Latitude; mc.Longitude = this.Longitude; return mc; }
92
5.5.2 以编程方式设置属性 在所使用的窗体类下面,创建一个称为 MapCoordinates 的新类。在该类内,实例化两个 Integer 来表示一组坐标的纬度和经度。 public class MapCoordinates { int Latitude; int Longitude; } 可以通过父窗体检索对话框数据,方法是访问创建的属性并将数据存储在一个对象中。
93
5.5.2 以编程方式设置属性 使用 MessageBox.Show 方法添加代码
调用 MessageBox 类的 Show 方法显示信息。对 Show 方法的调用使用可选的 style 参数,来指定在该消息框中显示的最适合于消息框类型的图标类型: public void PerformCalculations() { // 执行计算的代码由此进入 //显示一个告知用户计算已完成的消息框 MessageBox.Show ("The calculations are complete", "My Application", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk); } 消息框也可接受输入。MessageBox 类的 Show 方法返回用于确定用户所做选择的值。可以整数形式存储此值。也可使用 if 语句,比较显示消息框时返回的值。可设置 Show 方法的 Style 参数,以便显示适当的按钮向用户询问信息。
94
5.5.2 以编程方式设置属性 为类打开“代码编辑器”并定位到要为消息框添加代码的位置。添加使用 MessageBox 类的 Show 方法显示消息框的代码。下列代码演示如何调用 MessageBox 方法检索来自用户的信息,然后确定所选的值。 public void ExitApplication() { //显示一个消息框来询问用户他们是否要退出应用程序 if (MessageBox.Show ("Do you want to exit?", "My Application", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) Application.Exit(); }
95
5.6 多文档界面 (MDI) 多文档界面 (MDI)应用程序同时显示多个文档,每个文档显示在各自的窗口中。MDI 应用程序中常有包含子菜单的“窗口”菜单项,用于在窗口或文档之间进行切换。 5.6.1 创建 MDI 父窗体 多文档界面 (MDI) 应用程序MDI 父窗体是包含MDI 子窗口的窗体,在“Windows 窗体设计器”创建 MDI 父窗体很容易。首先创建 Windows 应用程序,在“属性”窗口中,将 IsMDIContainer 属性设置为 true,将该窗体指定为子窗口的 MDI 容器。注意,当在“属性”窗口中设置属性时,根据需要可将 WindowState 属性设置为 Maxmized,因为当父窗体最大化时操作 MDI 子窗口最为容易。另外,MDI 父窗体的边缘将采用系统颜色(在 Windows 系统控制面板中设置),而不采用Control.BackColor 属性设置的背景色。 将 MainMenu 组件从“工具箱”拖到窗体上,创建一个 Text 属性设置为“文件(&F)”的顶级菜单项,且带有“新建(&N)”和“关闭(&C)”的子菜单项。再创建一个名为“窗口(&W)”的顶级菜单项。第1个菜单将在运行时创建并隐藏菜单项,而第2个菜单将跟踪打开MDI 子窗口。此时,已创建了一个 MDI 父窗口。
96
5.6.1 创建 MDI 父窗体 按 F5 键运行该应用程序,如图5.16所示。 图5.16 运行结果
97
5.6.2 创建 MDI 子窗体 多文档界面 (MDI) 应用程序的基础是 MDI子窗体,因为它们是用户交互的中心。下面通过实例说明创建 MDI 子窗体的方法。 【例5.13】创建菜单结构中包含顶级菜单项“文件”和“窗口”及菜单项“新建”和“关闭”的 MDI 父窗体。 在“属性”窗口顶部的下拉列表中,选择与“窗口(&W)”菜单对应的菜单项,然后将 MDIList 属性设置为 true。这将使“窗口”菜单能够维护打开的 MDI 子窗口的列表(活动子窗口旁有一个复选标记)。 在“解决方案资源管理器”中,右击该项目,指向“添加”,单击“Windows 窗体”,此窗体将作为 MDI 子窗体的模板。在“添加新项”对话框中,从“类别”窗格选择“本地项目项”,并从右侧窗格选择“Windows 窗体”。在“名称”框中,命名窗体 Form2。单击“打开”按钮将该窗体添加到项目中。“Windows 窗体设计器”打开,其中显示 Form2。 将 RichTextBox 控件从“工具箱”拖到窗体上。在“属性”窗口中,将 Anchor 属性设置为“Top, Left”,并将 Dock 属性设置为“Fill”,这样,即使调整 MDI 子窗体的大小,RichTextBox 控件也会完全填充该窗体的区域。
98
5.6.2 创建 MDI 子窗体 为“新建”菜单项创建 Click 事件处理程序,单击“新建”菜单项,创建新的 MDI 子窗体。在下面的示例中,事件处理程序处理 MenuItem2 的 Click 事件。 protected void MDIChildNew_OnClick(object sender, System.EventArgs e) { Form2 newMDIChild = new Form2(); // 设置子窗体的父窗体 new MDIChild.MDIParent = this; // 显示一个新窗体. newMDIChild.Show(); } 按 F5 键运行该应用程序。请注意,在“文件”菜单中选择“新建” 菜单项,可创建新的 MDI子窗体,该子窗体在“窗口”菜单中被跟踪。
99
5.6.3 确定活动的 MDI 子窗体 一个 MDI 应用程序可以有同一个子窗体的多个实例,通过ActiveMDIChild 属性,可以得到当前具有焦点的子窗体或返回最近活动的子窗体。当窗体上有数个控件时,通过ActiveMDIChild 属性,可以得到当前活动的子窗体上有焦点的控件。 假定有一个 MDI 父窗体 (Form1),它具有包含 RichTextBox 控件的一个或多个 MDI 子窗口。 将活动子窗体的活动控件的文本复制到剪贴板。 protected void mniCopy_Click (object sender, System.EventArgs e) { // 确定活动的子窗体. Form activeChild = this.ActiveMDIChild; // 如果有一个活动的子窗体,找到活动的控件 // 在这个例子里是 RichTextBox. if (activeChild != null) try RichTextBox theBox = (RichTextBox)activeChild.ActiveControl; if (theBox != null)
100
5.6.3 确定活动的 MDI 子窗体 { // 把选择的文本放在剪贴板里.
Clipboard.SetDataObject(theBox.SelectedText); } Catch MessageBox.Show("You need to select a RichTextBox."); 通常,在多文档界面 (MDI) 应用程序的上下文中,需要将数据发送到活动子窗口,比如当用户将数据从剪贴板中粘贴到 MDI 应用程序中时。
101
5.6.3 确定活动的 MDI 子窗体 例如,将剪贴板上的文本复制到活动子窗体的活动控件,代码如下:
protected void mniPaste_Click (object sender, System.EventArgs e) { //确定活动的子窗体. Form activeChild = this.ActiveMDIChild; // 如果有一个活动的子窗体,找到活动的控件 // 在这个例子里是RichTextBox. if (activeChild != null) Try RichTextBox theBox = (RichTextBox)activeChild.ActiveControl; if (theBox != null)
102
5.6.3 确定活动的 MDI 子窗体 { // 创建一个新的数据对象接口的实例
IDataObject data = Clipboard.GetDataObject(); // 如果数据是文本, 那么把 RichTextBox 的文本复制到剪贴板 if (data.GetDataPresent(DataFormats.Text)) theBox.SelectedText = data.GetData(DataFormats.Text). ToString(); } Catch MessageBox.Show("You need to select a RichTextBox.");
103
5.6.4 排列子窗体 应用程序通常包含对打开的 MDI 子窗体进行操作的菜单命令,如“平铺”、“层叠”和“排列”。可以使用LayoutMdi方法和MdiLayout枚举来重新排列 MDI 父窗体中的子窗体。 LayoutMdi方法可使用4个不同 MdiLayout 枚举值中的一个,这些枚举值将子窗体显示为层叠、水平平铺或垂直平铺,或者在 MDI 窗体下部显示排列的子窗体图标。这些方法常用于菜单项Click 事件处理程序。这样,选择菜单项可在 MDI 子窗口上产生所需的效果。 为了排列子窗体,用 LayoutMdi 方法为 MDI 父窗体设置 MdiLayout 枚举。例如,对 MDI 父窗体 (Form1) 的子窗口使用 MdiLayout 枚举的“层叠”设置。在“层叠窗口”菜单项“单击”事件处理中使用下列代码: protected void CascadeWindows_Click(object sender, System.EventArgs e) { myForm1.LayoutMdi(System.Windows.Forms.MdiLayout.Cascade); }
104
5.7 打印与打印预览 在 Windows 窗体中打印包括使用PrintDocument 组件进行打印,使用 PrintPreviewDialog 控件、PrintDialog 和 PageSetupDialog 组件,提供熟悉的Windows 操作系统的图形用户界面。 通常,先创建 PrintDocument 组件的一个实例,使用 PrinterSettings 和 PageSettings 类设置描述打印内容的属性,然后调用 Print 方法实际打印文档。 在从 Windows 应用程序进行打印的过程中,PrintDocument 组件将显示中止打印对话框,该对话框提醒用户正在进行打印,并且可让用户取消打印作业。 在 Windows 窗体中实现打印的基础是 PrintDocument 组件,通过编写PrintPage 事件处理代码,可以指定打印内容和打印方式。
105
5.7.1 在设计时创建打印作业 向窗体中添加 PrintDocument 组件,右击窗体并选择“查看代码”, PrintPage 事件处理必须编写自己的打印逻辑代码,也必须指定要打印的材料。通过使用“属性”窗口的“事件”选项卡来连接该事件。 例如,在 PrintPage 事件处理程序中创建一个示例图形(红色矩形)作为要打印的材料,代码如下: private void printDocument1_PrintPage(object sender, System.Drawing.Printing. PrintPageEventArgs e) { e.Graphics.FillRectangle(Brushes.Red, new Rectangle(500, 500, 500, 500)); } 一般在设计时设置与打印相关的选项,但用户有时希望在运行时以编程方式更改选项,通过 PrintDialog 组件和 PrinterSettings 类可实现此目的。例如,将 PrintDialog 组件从工具箱添加到窗体中,右击窗体并选择“查看代码”,使用 ShowDialog 方法显示 PrintDialog 组件。代码如下: printDialog1.ShowDialog();
106
5.7.2 选择打印机打印文件 【例5.14】使用 PrintDialog 组件选择要使用的打印机。
有两个要处理的事件。在第1个事件(Button 控件的 Click 事件)中,实例化 PrintDialog 类,并在 DialogResult 属性中捕获用户选择的打印机。在第2个事件(PrintDocument 组件的 PrintPage 事件)中,将一个示例文档打印到指定的打印机。 private void button1_Click(object sender, System.EventArgs e) { PrintDialog printDialog1 = new PrintDialog(); printDialog1.Document = printDocument1; DialogResult result = printDialog1.ShowDialog(); if (result == DialogResult.OK) printDocument1.Print(); } private void printDocument1_PrintPage(object sender, System.Drawing.Printing.Print PageEventArgs e) e.Graphics.FillRectangle(Brushes.Red, new Rectangle(500, 500, 500, 500));
107
5.7.3 打印图形 通常,在 Windows 应用程序中打印图形,Graphics 类提供将对象绘制到设备(如屏幕或打印机)的方法。
将 PrintDocument 组件添加到窗体中。右击窗体并选择“查看代码”,在 PrintPage 事件处理程序中,使用 PrintPageEventArgs 类的 Graphics 属性指示打印机打印何种图形。 【例5.15】使用事件处理程序在边框中创建一个蓝色的椭圆,其位置和尺寸如下:以 (100,150) 为起点,宽度和高度均为 250。 private void printDocument1_PrintPage(object sender, System.Drawing.Printing. PrintPageEventArgs e) { e.Graphics.FillRectangle(Brushes.Blue, new Rectangle(100, 150, 250, 250)); }
108
5.7.4 打印文本 对 Windows 应用程序来说,打印文本非常常见。Graphics 类提供将对象(图形或文本)绘制到设备(如屏幕或打印机)的方法。 将 PrintDocument 组件添加到窗体中。右击窗体并选择“查看代码”,在 PrintPage 事件处理程序中,使用 PrintPageEventArgs 类的 Graphics 属性指示打印机打印何种文本。例如,使用事件处理程序从点 (150,125) 开始用黑色的 Arial 字体打印字符串“SampleText”,代码如下: private void printDocument1_PrintPage(object sender, System.Drawing.Printing. PrintPageEventArgs e) { e.Graphics.DrawString("SampleText", new Font("Arial", 80, FontStyle.Bold), Brushes.Black, 150, 125); }
109
5.7.4 打印文本 下面的过程假定已经创建了一个 Windows 应用程序,在该应用程序中有一个 PrintDocument 组件,这是从 Windows 应用程序进行打印的标准方式。 (1) 在“属性”窗口中,设置 PrintDocument 组件的 DocumentName 属性,或者在代码中设置: printDocument1.DocumentName = "MyTextFile"; (2) 右击窗体并选择“查看代码”,编写代码以处理 EndPrint 事件。显示一个消息框,指示文档已完成打印。 private void printDocument1_EndPrint (object sender, System.Drawing.Printing.PrintPageEventArgs e) { MessageBox.Show(printDocument1.DocumentName + " has finished printing."); } 应用程序的一个通用功能是打印预览,在打印预览中屏幕显示要打印的文档。Windows 窗体通过 PrintPreviewDialog 控件提供此功能。另外,如果要自定义完成打印预览功能,可使用工具箱内的 PrintPreviewControl。
110
5.8 综合应用实例 【例5.16】窗体、对话框类的使用。包括一个MDI主窗体类、一个MDI子窗体类、一个对话框类。 步骤如下:
1. 新建一个项目 运行Visual Studio .Net,选择“文件”菜单的“新建”选项,打开“新建项目”对话框,在“项目类型”中选择“Visual C#项目”,在“Windows应用程序”选项“名称”中输入新项目的名字,确定保存路径以后单击“确定”按钮。 2.创建主窗体和对话框 首先将系统提供的窗体类的text属性设置为“主窗口”,同时把窗体的名字Form1改为“MainForm”并相应改变Main方法引用的主窗体的类名。 Application.Run(new MainForm()); 设置MainForm的IsMdiContainer属性为True。 在“解决方案资源管理器”中选择本项目,在单击右键出现的快捷菜单中选择“添加”选项中的“添加新项目”命令,打开“添加新项”对话框。在该对话框中,从左边的“类别”列表框选择本地项目,在右边的“模版”列表框中选择“Windows窗体”,输入新窗体的名称AboutDialog.cs,单击“打开”,生成新的窗体。打开“属性”窗口对话框,把新添加的窗体的BorderStyle属性改为FixedDialog,并且把Text属性改为“关于”。
111
【例5.16】 使用同样的步骤创建MDIChildForm窗体,把它作为MDI子窗体,然后为这个窗体添加主菜单,它包含一个菜单项,标题为“MDI子窗体的菜单”。 添加主菜单和快捷菜单 用窗体设计器为主窗体添加菜单,结构如表5.8 。 表5.8 主菜单的结构
112
【例5.16】 4. 添加事件处理方法 使用“属性”窗口为主菜单的各个菜单项的Click 事件添加下列处理方法:
4. 添加事件处理方法 使用“属性”窗口为主菜单的各个菜单项的Click 事件添加下列处理方法: static void Main() { Application.Run(new MainForm()); } private void MainForm_Load(object sender, System.EventArgs e) private void miEixt_Click(object sender, System.EventArgs e) Form[] children=this.MdiChildren; for (int i=0;i<children.Length ;i++) children[i].Close(); this.Close ();
113
【例5.16】 private void miAbout_Click(object sender, System.EventArgs e)
{ AboutDialog aboutdlg= new AboutDialog (); aboutdlg.ShowDialog (); } private void miNew_Click(object sender, System.EventArgs e) MDIChildForm childl=new MDIChildForm (); childl.MdiParent=this; childl.Show(); private void mmiClose_Click(object sender, System.EventArgs e) this.ActiveMdiChild .Close ();
114
【例5.16】 private void miTile_Click(object sender, System.EventArgs e) {
this.LayoutMdi(System.Windows.Forms.MdiLayout.TileHorizontal); } private void miCascade_Click(object sender, System.EventArgs e) this.LayoutMdi(System.Windows.Forms.MdiLayout.Cascade); 运行结果如图5.17、图5.18和图5.19所示。
115
【例5.16】 图5.17 运行结果 图5.18 运行结果 图5.19 运行结果
Similar presentations