一、菜单MenuStrip控件
在Windows环境下,几乎所有的应用程序都通过菜单实现各种操作。
对C#语言应用程序来说,当操作比较简单时,一般通过控件来执行。
而当操作复杂时,可利用菜单把有关的应用程序组织在一起,通过单击特定的菜单项执行特定任务。
可见,设计友好、规范的菜单对于设计高质量的应用程序有着十分重要的意义。
二、菜单的组成
1.下拉式菜单的组成
1)菜单栏。
菜单栏置于窗体标题下方,包含每个菜单标题。
2)菜单标题。
菜单标题又称为主菜单,其中包括命令列表或子菜单名等若干个选择项。
3)菜单项。
菜单项又称子菜单,可以逐级下拉。
菜单项可以是命名、选项、分隔条或子菜单标题。
每个菜单项都是一个控件,有自己的属性和事件。
菜单项的各组成部分及其特点有如下几种:
(1)命令
命令菜单可以直接执行动作。
(2)选项
选项菜单可以打开对话框,这样的菜单项右边一般含有省略号。
(3)分割条
分割条是在菜单项之间的一条水平直线,用于将菜单项按功能分组。
(4)子菜单标题
单击子菜单标题将显示其下的子菜单项,这样的菜单项右则一般含有右向箭头。
三、菜单的设计
1.添加菜单
在【工具】窗口中的【菜单和工具栏】栏中把MenuStrip控件拖到窗口中,这时会在窗体中显示一个空白的菜单栏。
左边有【请在此处键入】字样。
这个控件也会出现在窗体外下方的区域。
单击窗体上方菜单栏或者下方的menuStrip图标都可以选中菜单。
这时所添加的菜单还是一个空白菜单。
2.添加菜单
就是在【请在此处键入】上添加名称,子集会自动生成,如果需要就填,不需要就不填。
3.添加菜单项
在控件上右键,弹出菜单后选择【插入】添加新菜单。
在【插入】中有4个类型控件。
1)MenuItem:菜单项。
2)ComboBox:组合框,一般很少使用。
3)Separator:分割条。
在显示“请在此处键入”的白色区域内直接输入“-”也可以创建一个分割条。
4)TextBox:文本框。
其中MenuItem是最常使用的项,是一个ToolStripMenuItem控件,有如下常用属性。
1)Checked:
指示该项是否处于勾选的状态,如果它的值设置为true,可以在菜单项左边显示一个勾号。
2)Image:
可以通过Image属性给菜单项指定一个图标。
3)ShortcutKeys:
给菜单项指定一个快捷性。
4)ShowShortcutKeys:
指示是否在该菜单项显示器快捷键。
5)ShortcutKeyDisPlayString:
给菜单项的快捷键自定义一个描述信息,如果它为空白则会显示系统定义的快捷键描述信息。
6)ToolTipText:
在鼠标移动到菜单项时显示的提示信息。
4.添加子菜单标题
如果在一个子菜单中又添加子菜单,那么它将自动成为一个子菜单标题。
总之就是添加就行了?
5.给菜单添加事件
双击所选的菜单项会生成Click事件,要想生成其他事件,就得去事件面板里找了。
四、工具栏ToolStrip控件
已经成为Windows应用程序的标准功能。
工具栏提供了应用程序中常用菜单命令的快捷访问。
它一般由多个按钮排列组成,每个按钮对应菜单中的某一菜单项,运行时,单击工具栏中的按钮就可以快速执行对应操作。
1.添加工具栏
在【工具】窗口中的菜单和工具栏中把ToolStrip控件拖到窗口中。
这时会在窗体中显示一个空白的工具栏,左边有一个带向下箭头的图标。
单击窗体上方工具栏或者下方的toolStrip1图标都可以选中工具栏。
2.添加项
单击如图工具栏左边的带有向下箭头的小图标可以在工具栏中添加一个项。
ToolStrip中可以添加以下8种控件。
1)Button:
工具按钮,这是工具栏上最常见的控件。
2)Label:
文本标签。
3)SplitButton:
一个左侧标准按钮和右侧下拉按钮的组合。
它可以通过右侧下拉按钮所显示的列表选择一个左侧显示的按钮。
4)DropDownButton:
与SplitButton极其相似。
它们之间的区别在于单击SplitButton左侧按钮时不会弹出下拉列表,而单击DropDowunButton左侧按钮时会弹出下拉列表。
两者的子菜单设置十分相近。
5)Separator:
分隔线,用于对ToolStrip上的其他项进行分组。
6)ComboBox:
组合框。
7)TextBox:
文本框。
8)ProgressBar:
进度条。
3.添加事件
由于工具栏中最常用的项是按钮(Button),这里只针对按钮的事件进行讲述。
双击一个按钮,就会生成Click事件。
同样也可以通过事件面板,生成其他事件。
例:ItemClicked事件有两个参数
第一个参数代表发出事件的项;
第二个参数代是一个ToolStripItemClickedEventArgs类型。这个类包含一个ClickedItem属性,这个属性返回的是发生单击事件的项。
由于ToolStrip上所能容纳的项都继承自ToolStripItem,可以把发生单击事件的项强制转化成ToolStripItem进行处理。
五、MDI窗体
用于MDI窗体的应用程序也称为多文档界面应用程序,每个文档显示在各自的窗口中,每个窗口(MDI窗口)都包含在主窗体之内。
微软的Excel和Access就是多文档界面的应用程序。
1.MDI窗体的创建
多文档界面MDI应用程序的基础是MDI父窗体,它是包含MDI子窗口的窗体。
MDI子窗口是用户与MDI应用程序在其中进行交互的子窗口。
可以使用以下方法创建一个MDI应用程序。
1)把作为MDI父窗体的IsMDIContainer属性设置为true。
2)新建一个窗体(假设窗体名为Form2)作为MDI子窗体。
3)在MDI父窗体中调用如下代码即可显示一个MDI子窗体:
总之就是:
1)先创建一个Windows应用程序,
2)然后在新建窗口里找到MDI父窗体,并将IsMDIContainer属性改成true。
3)再新建一个Windows窗体Form2,并作为MDI窗体的子窗体。
4)然后在MDI父窗体中,双击生成Load事件。
5)再将应用程序的主入口点改成MDI父窗体的Name
2.MDI窗体的排列
应用程序常包含对打开的MDI子窗体进行操作的菜单命令,如“平铺”、“层叠”、“排列”。
可以在MDI父窗体中使用LayoutMdi方法重新排列子窗体,
this.LayoutMdi(MdiLayout.ArrangeIcons);
LayoutMdi方法可以使用如下4个枚举值的一个。
1)ArrangeIcons:
所有MDI子图标均排列在MDI父窗体的工作区内,这一选项只对最小化的窗口有效。
2)Cascade:
所有MDI子窗口均层叠在MDI父窗体的工作区内。
3)TileHorizontal:
所有MDI子窗口均水平平铺在MDI父窗体的工作区内。
4)TileVertical:
所有MDI子窗口均垂直平铺在MDI父窗体的工作区内。
这些方法常用作由菜单项的Click事件调用的事件处理程序,这样文本为“层叠窗口”的菜单项可在MDI子窗口上产生所需效果。
六、实例演示
演示MenuStrip、ToolStrip以及MDI窗体的使用。
1.简易文本编辑器。
1)新建一个Windows应用程序项目。
2)修改窗体属性,Name:MainForm;Text:文本编辑器;IsMdiContainer属性设置为true。
3)在MainForm上放置一个MenuStrip,不更改命名。
但要往里面添加菜单和改变Name属性,Text属性。
4)在【格式】菜单的子菜单中的“粗体”、“斜体”、“下划线”。
分别找到image属性,然后点击右侧的添加按钮,往里面添加相应的图片。如上图
(由于没有合适的图片,所有也就随便找些图片就好)
5)在MainForm窗体上再放置一个ToolStrip控件,并添加3个工具按钮,(右键插入Button)。
同样找到Image属性,并加入图片。
然后在Text属性分别添加“粗体”、“斜体”、“下划线”。
6)再新建一个windows窗口,作为新建窗口。
Name属性:frmMDIChild;
然后再添加一个RichTextBox控件,跟输入框类似。
Dock属性:Fill;使其充满整体窗体。
7)分别双击【文件】下的子菜单“新建”和“退出”,生成Click事件。
8)按住Ctrl,同时选中【格式】下的子菜单“粗体”、“斜体”、“下划线”,并在事件面板里双击Click事件。使它们共享一个事件。
9)再同时选中【窗口】下的子菜单“平铺”、“层叠”、“水平并排”、“垂直并排”,并生成Click事件。使它们共享一个事件。
10)选中ToolStrip控件,也就是“窗体工具栏”。
并生成ItemClicked事件。
整体代码如下:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace WindowsFormsApplication33{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private int mdiChildCount = 0;//用于记录打开MDI子窗体的次数 private void mitemNew_Click(object sender, EventArgs e) { mdiChildCount++; //每打开一个MDI子窗体就+1 frmMDIChild mdiChild = new frmMDIChild(); //创建一个新的MDI子窗体 mdiChild.MdiParent = this; //作为子窗体显示 mdiChild.Show(); mdiChild.Text = "文档" + mdiChildCount.ToString();//更改窗体标题 } private void mitemExit_Click(object sender, EventArgs e) { //退出 Close(); } private void mitemBlod_Click(object sender, EventArgs e) { //直接调用自定义函数 formatText(((ToolStripItem)sender).Text); } private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //直接调用自定义函数 formatText(((ToolStripItem)e.ClickedItem).Text); } private void mitemForm_Click(object sender, EventArgs e) { //根据菜单项的Text属性来区分它们 switch (((ToolStripItem)sender).Text) { //重新排列MDI子窗体 case "平铺": this.LayoutMdi(MdiLayout.ArrangeIcons); break; case "层叠": this.LayoutMdi(MdiLayout.Cascade); break; case "水平并排": this.LayoutMdi(MdiLayout.TileHorizontal); break; default: this.LayoutMdi(MdiLayout.TileVertical); break; } } private void formatText(string itemText) { //寻找处于激活状态下的MDI子窗体 Form activeChild = this.ActiveMdiChild; if(activeChild != null)//如果找到 { //寻找MDI子窗体上的处于活动状态的RichTextBox控件 RichTextBox aBox = (RichTextBox)activeChild.ActiveControl; if(aBox != null) { //提取RichTextBox中的选中的文字字体 Font fontOfSelectedText = aBox.SelectionFont; FontStyle fs; switch (itemText)//根据菜单项或工具按钮的Text属性来区它们。 { //更改字体样式,并存放在FontStyle类型变量fs中 case "粗体": fs = aBox.SelectionFont.Bold ? FontStyle.Regular : FontStyle.Bold; break; case "斜体": fs = aBox.SelectionFont.Italic ? FontStyle.Regular : FontStyle.Italic; break; default: fs = aBox.SelectionFont.Underline ? FontStyle.Regular : FontStyle.Underline; break; } Font FontToApply = new Font(fontOfSelectedText, fs); aBox.SelectionFont = FontToApply;//更改选中部分的字体样式 } } } }}
运行结果
由于太长,所以先进行分段:
从20行~99行
20行
是用来记录子窗口打开的次数;
以便在打开MDI窗体时在其标题上显示文档序号。
21~28行
是【文件】菜单下的“创建”的单击事件。
目的就是创建新窗口,就像ps软件的新建画布?
24~26行,就是之前提到的MDI窗体的创建。(其实也就是窗体的创建。)
27行是给窗体标号。
30~34行
是【文件】菜单下的“关闭”的单击事件。
实现程序关闭效果。
36~40行
是【格式】菜单下的“粗体”、“斜体”、“下划线”共用单击事件。
自定义函数,实现“粗体”、“斜体”、“下划线”的效果。
它把sender参数强制转化成ToolStripItem类型,并访问它们的Text属性。
通过传递Text属性的值,来改变字体的效果。
42~46行
是工具栏,ToolStrip控件的ItemClicked事件。
同样通过获取Text属性值,从而改变属性。
通过事件参数e的ClickedItem属性,提取出所单击按钮对象。
再强制转化为ToolStripItem类型,并访问它们的Text属性。
47~66行
通过swith语句来区分菜单项的Text属性,并进行不同的处理。
68~99行
就是自定义的属性,同样根据Text属性值来进行不同效果的处理。
将选中的文本加上不同字体样式。
Form activeChild = this.ActiveMdiChild; if(activeChild != null)//如果找到 { //寻找MDI子窗体上的处于活动状态的RichTextBox控件 RichTextBox aBox = (RichTextBox)activeChild.ActiveControl; if(aBox != null) { //进行相应处理 } }
这部分用于寻找处理激活状态的MDI窗体的正在进行标记的RichTextBox控件。
这里首先把MDI父窗体的处理激活状态的MDI子窗体赋给一个窗体变量activeChild,然后利用activeChild的ActiveControl属性返回处理激活状态的控件,并把它强制转化成RichTextBox类型。