MDI应用程序介绍 |
在VC#中,MDI应用程序由两部分组成,即MDI父窗体和MDI子窗体。
一个MDI应用程序可以包含一个或多个MDI父窗体,每个MDI父窗体又可以包含多个MDI子窗体。一个MDI父窗体可以包含所有MDI子窗体。
在VC#中,一个MDI父窗体可以包含多个MDI子窗体,但它不能同时作为另一个MDI父窗体。
换句话说,一个窗体不能既是MDI父窗体,又是MDI子窗体。
在MDI父窗体中,MDI子窗体是作为独立的窗口显示的,用户通过MDI子窗口和MDI父窗口,与MDI应用程序交互。因此在VC#中,你可以在一个MDI应用程序中集成多个窗口。为了在设计或运行时创建MDI父窗体,你可以将窗体的IsMdiContainer属性设置为true。
MDI应用程序支持多个子窗体实例,因此它必须知道应该在那个实例上执行操作。要获取具有焦点或最近处于活动状态的子窗体实例,你可以使用ActiveMdiChild属性。
例如,下面代码将返回活动的MDI子窗体对象:
Form activeChildForm=this.ActiveMdiChild;
MDI应用程序可能包含多个窗口或文档,因此你需要提供窗口或文档间的一种切换机制。你可以通过为MDI应用程序创建菜单,使得用户能够在多个窗口或文档间切换。
默认情况下,打开包含菜单的子窗体时,子窗体上的菜单将被添加到MDI父窗体菜单和末尾。菜单的融合 可以使用ToolStripMenuItem控件的MergeAction和MergeIndex属性实现。默认情况下,MergeAction属性的值为Append,这意味着菜单将被融合到MDI父窗体菜单的末尾。
布局MDI子窗体 |
一个MDI应用程序由多个窗体组成。在某些情况下,用户可能需要同时打开多个子窗体。此时,用户需要合理排列MDI了窗体,以便可以同时操作多个子窗体。
Windows应用程序允许用户一次打开多个文件。在操作多个文件时,用户需要合理布局屏幕上的文件,以便提高工作效率。所有基于Windows的应用程序都有个称作Window的菜单,其中的选项可以用来排列所有打开的窗口。
为了排列MDI父窗体中打开的子窗体,你需要编写如下的代码:
①this.LayoutMdi(MdiLayout.ArrangeIcons);
所有MDI子图标都排列在MDI父窗体的客户区。如下图所示:
②this.LayoutMdi(MdiLayout.Cascade);
所有MDI子窗口都层叠排放在MDI父窗体的客户区。如下图所示:
③this.LayoutMdi(MdiLayout.TitleVertical);
所有MDI子窗口都水平层叠在MDI父窗体的客户区。如下图所示:
④this.LayoutMdi(MdiLayout.TitleHorizontal);
所有MDI子窗口都垂直层叠在MDI父窗体的客户区。如下图所示:
总之,所有MDI应用程序都有个Window菜单。该菜单包含了所有打开的子窗口的名称。这个特性可以通过Windowlist属性集成到VC#应用程序中。
练习 |
选择题:
ToolStripMenuItem控件的MergeAction属性的默认值是什么?
A:Append
B:Insert
C:Replace
D:Remove
答案:A
小结 |
u 利用MDI应用程序,可以在同一程序中打开多个窗体。
英语词汇 |
英文 中文
MDI:Multi-Document Interface 多文档界面
实践项目 |
创建一个MDI应用程序并使其按上面所提到的四种方式排列。
WinForm控件简介 |
我们自己动手开发的WinForm控件通常有三种类型:复合控件(Composite Controls),扩展控件(Extended Controls),自定义控件(Custom Controls)。
复合控件(用户控件):将现有的各种控件组合起来,形成一个新的控件,集成现有控件的功能和特性。复合控件继承自System.Windows.Forms.UserControl类。
扩展控件:在现有控件的控件的基础上派生出一个新的控件,为原有控件增加新的功能、特性或者修改原有控件的功能、特性。
自定义控件:扩展控件和复合控件不能满足我们需要时,需要我们编写自己的控件。自定义控件从System.Windows.Forms.Control类继承而来。Control类提供控件所需要的所有基本功能,包括键盘和鼠标的事件处理。自定义控件的定制程度最高,但是对开发者的要求也比较高,你必须为Control类的OnPaint事件写代码,你也可以重写Control类的WndProc方法,处理更底层的Windows消息,所以需要了解一些GDI+和Windows API方面的知识。一般情况下复合控件和扩展控件是我们常用的作法,我们将主要介绍复合控件和扩展控件的开发应用。
创建复合控件 |
在此我们举例创建一个简单的登录框复合控件。该控件将实现自动判断用户名和密码功能:如果用户名或密码为空弹出“用户名或密码不能为空”提示;如果用户名和密码都不为空则打开指定的窗体,隐藏当前窗体。
一、 创建控件库
在VS中单击“文件”菜单->”新建”->”项目”,弹出“新建项目”对话框。在左边“项目类型”中选择“Visual C#”,右边“模板”中选择”Windows 控件库”,填写项目名称”MyControl”,填写项目位置,单击“确定”按钮创建我们的控件库。
二、 创建控件
1、在解决方案资源管理器中的“MyControl“项目上单击鼠标右键依次“添加”->”用户控件”,弹出“添加新项”对话框,选中“用户控件”,在名称栏输入“Login”单击“添加”按钮即可创建一个新的空白用户控件。
2、在布置新建的用户控件如图样子。
使用到的控件列表
控件标识 |
说明 |
btnLogin |
登录按钮 |
btnCancel |
取消按钮 |
txtName |
用户名输入框 |
txtPwd |
密码输入框 |
3、添加属性
privatebool _IsPassed = true;
privateForm _ToForm = null;
///
///判断登录是否成功,如果成功值为真,否则值为假
///
[Category("自定义属性")]
[Description("判断登录是否成功,如果成功值为真,否则值为假")]
public bool IsPassed
{
get{ return _IsPassed; }
set{ _IsPassed = value; }
}
///
///如果登录成功,则打开该处指定的窗体
///
[Browsable(false)]//该设置使该属性不在控件的属性设计器中显示
public Form ToForm
{
get{ return _ToForm; }
set{ _ToForm = value; }
}
IsPassed属性在此我们只作演示,没有在代码中使用到,它会在控件的属性设计器中显示出来。ToForm属性不会在控件的属性设计器中显示出来,但是我们在代码中使用到了,用于指定登录验证成功后要显示的窗体。
4、添加登录按钮事件方法
//登录按钮
privatevoid btnLogin_Click(objectsender, EventArgs e)
{
//如果用户名或密码为空
if(String.IsNullOrEmpty(txtName.Text) || String.IsNullOrEmpty(txtPwd.Text))
{
MessageBox.Show("用户名或密码不能为空!");
_IsPassed = false;//登录失败
}
else//如果用户名和密码都不为空
{
if(_ToForm != null)
{
_ToForm.Show();//打开目标窗体
this.FindForm().Hide();
}
}
}
5、添加取消按钮事件处理
//取消按钮
private void btnCancel_Click(objectsender, EventArgs e)
{
Form loginForm = this.FindForm();
if (loginForm != null)
{
loginForm.Close();
}
}
在“解决方案资源管理器”中右键点击“MyControl”项目->”生成”,生成我们的控件库。至次我们的登录控件大功告成。先乐呵乐呵,噢耶!噢耶!
使用复合控件 |
一、 创建Windows应用程序
在VS中单击“文件”菜单->”新建”->”项目”,弹出“新建项目”对话框。在左边“项目类型”中选择“Visual C#”,右边“模板”中选择”Windows应用程序”,填写项目名称”MyWin”,填写项目位置,单击“确定”按钮创建我们的Windows应用程序。
二、 创建使用登录控件的窗体FrmLogin
在解决方案资源管理器中的“MyWin“项目上单击鼠标右键依次“添加”->”Windows窗体”,弹出“添加新项”对话框,选中“Windows窗体”,在名称栏输入“FrmLogin”单击“添加”按钮即创建登录窗体。
三、 将登录控件添加到工具箱
右键点击“工具箱”->”选择项”->弹出“选择工具箱项”对话框,单击“浏览”按钮,选中我们创建的控件库编译生成的dll文件。
四、 将登录控件从工具箱拖放到FrmLogin窗体上并声明其标识为myLogin,如图所示
五、 添加登录验证成功后要打开的窗体FrmMain,如图所示:
六、 给FrmLogin的窗体加载事件中添加如下代码:
privatevoid FrmLogin_Load(objectsender, EventArgs e)
{
FrmMainfrmMain = new FrmMain();
myLogin.ToForm = frmMain;//设定窗体FrmMain为验证成功时要打开的窗体
}
运行我们的MyWin项目。点击“登录”按钮打开FrmMain窗体,隐藏登录窗体;点击“取消”按钮关闭登录窗体。
创建扩展控件 |
除了复合控件,扩展控件也是我们常用到的。我们将通过创建一个只能输入数字的文本框给大家介绍怎样开发扩展控件。
创建控件
1、 在解决方案资源管理器中的“MyControl“项目上单击鼠标右键依次“添加”->”组件”,弹出“添加新项”对话框,选中“组件类”,在名称栏输入“MyTextBox”单击“添加”按钮就创建一个新的组件。
2、 切换到组件的“代码视图”,修改继承类为TextBox。代码如下:
public partial class MyTextBox : TextBox
{
public MyTextBox()
{
InitializeComponent();
}
private voidMyTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;//阻止键盘输入
if (e.KeyChar >= '0' && e.KeyChar <= '9' || e.KeyChar == (char)8)
{
e.Handled = false;//如果是数字或是删除键,不阻止键盘输入
}
}
}
3、 切换到组件的“设计视图”,调用出“属性设计器”,添加“KeyPress”事件,其代码如下:
private voidMyTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;//阻止键盘输入
if (e.KeyChar >= '0' && e.KeyChar <= '9' || e.KeyChar == (char)8)
{
e.Handled = false;//如果是数字或是删除键,不阻止键盘输入
}
}
4、 编译生成我们的控件。
使用扩展控件 |
一、 创建使用登录控件的窗体FrmTextBox
在解决方案资源管理器中的“MyWin“项目上单击鼠标右键依次“添加”->”Windows窗体”,弹出“添加新项”对话框,选中“Windows窗体”,在名称栏输入“FrmTextBox”单击“添加”按钮即创建窗体。
二、 将控件添加到工具箱
右键点击“工具箱”->”选择项”->弹出“选择工具箱项”对话框,单击“浏览”按钮,选中我们创建的控件库编译生成的dll文件。
三、 将数字文本框控件从工具箱拖放到FrmTextBox窗体上,运行应用程序如图:
实践问题 |
选择题:
1. 复合控件继承自哪个类?__________
A. System.Windows.Forms.Form B. System.Windows.Forms.Object
C. System.Windows.Forms.UserControl D. System.Windows.Form.UserControl
2. 我们自己动手开发的WinForm控件通常有哪些类型__________
A.手写控件 B.扩展控件
C.复合控件 D.自定义控件
小结 |
在本章中,我们主要学习了:
u 复合控件
u 扩展控件
u 使用复合控件
练习项目 |
1. 制作一个只允许输入字母的文本框控件。
2. 做一个QQ的登录复合控件。