2019-8-15C#MDI窗体实现多窗口效果
Visual C#是微软公司推出的下一代主流程序开发语言,他也是一种功能十分强大的程
序设计语言,正在受到越来越多的编程人员的喜欢。在Visual C#中,提供了为实现MDI程序设计的很多功能。本文就是通过一个具体的例子来详细的介绍在Visual C#中的MDI编程。
一程序设计及运行的环境:
(1)视窗2000服务器版
(2).Net FrameWork SDK Beta 2版
二程序设计的思路、主要步骤和实现方法:
MDI编程主要就是要在主窗体中能够新建一个MDI窗体,并且能够对主窗体中的所有MDI窗体实现层叠、水平平铺和垂直平铺。虽然这些操作比较基本,但却是程序设计中的要点和重点。本文就按照上述功能的顺序来一一介绍。
(1)首先要设定主窗体是一个MDI窗体的容器,因为只有如此才能够在此主窗体上面添加MDI窗体,从而实现对MDI编程,具体实现语句如下:
public Form1()
{
InitializeComponent();
this.IsMdiContainer = true;
}
我是直接把this.IsMdiContainer = true ;写在窗体的构造函数中,你也可以写的form_load函数中。
(2)在主窗体上面新建一个MDI窗体。在程序中,新建一个MDI窗体的命令是通过一个菜单的事件来实现的。在处理新建一个MDI窗体事件中,关键是要设定此MDI窗体的父窗体。其实MDI窗体和别的窗体没有什么不同,不同点就在MDI窗体有上一级窗体,即父窗体,而其他窗体是没有的,具体实现语句如下:
private void New_Click ( object sender , EventArgs e )//这是一个菜单的事件
{
Form frmTemp = new Form ( ) ;
//新建一个窗体
frmTemp.MdiParent = this ;
//定义此窗体的父窗体,从而此窗体成为一个MDI窗体
frmTemp.Text = "窗体0" + FormCount.ToString ( ) ;
//设定MDI窗体的标题
FormCount++ ;
frmTemp.Show ( ) ;
//把此MDI窗体显示出来
}
(3)实现对MDI窗体的层叠:
对于在主窗体中实现对MDI窗体的层叠操作,在主程序中,是通过一个方法来实现的,这个方法就是LayoutMdi,他所带的参数是MdiLayout.Cascade,具体实现语句如下:
private void Cascade_Click ( object sender , EventArgs e ) //实现对主窗体中的MDI窗体的层叠操作
{
this.LayoutMdi ( MdiLayout.Cascade ) ;
}
实现操作后具体如下图:
图01:在主窗体中实现对MDI窗体的层叠操作,点击小图放大
要在主窗体实现MDI窗体水平平铺,也是通过LayoutMdi方法,此时所带的参数是MdiLayout.TileHorizontal,具体实现语句如下:
this.LayoutMdi ( MdiLayout.TileHorizontal ) ;
要在主窗体实现MDI窗体垂直平铺,也是通过LayoutMdi方法,此时所带的参数是MdiLayout.TileVertical,具体实现语句如下:
this.LayoutMdi ( MdiLayout.TileVertical ) ;//实现对主窗体中的MDI窗体的垂直平铺操作
图03:在主窗体中实现对MDI窗体的垂直平铺操作,点击小图放大
WindowMenu.MdiList = true ;本程序中,是在"窗口"主菜单项下面加入MDI窗体的子菜单项的。加入此语句后,程序运行界面具体如下图:
三.程序源代码(mdi.cs)及编译方法:
通过对程序设计中的难点介绍以后,就可以比较容易得到实现对上述MDI窗体处理的源程序代码(mdi.cs),具体如下:
mdi.cs源程序代码:
using System ;
using System.Windows.Forms ;
using System.ComponentModel ;
using System.Drawing ;
//导入在程序中用到的名称空间
class MDIDemo : Form
{
private static int FormCount = 1 ;
//定义此常量是为了统计MDI窗体数目,
MainMenu mnuMain = new MainMenu ( ) ;
MenuItem FileMenu ;
MenuItem NewMenu ;
MenuItem ExitMenu ;
MenuItem WindowMenu ; public MDIDemo ( )
{
this.IsMdiContainer = true ;
this.Text = "MDI演示程序" ;
FileMenu = new MenuItem ( ) ;
FileMenu.Text = "文件" ;
WindowMenu = new MenuItem ( ) ;
WindowMenu.Text = "窗口(&W)" ;
WindowMenu.MenuItems.Add ( "窗体层叠(&C)" , new EventHandler ( Cascade_Click ) ) ;
WindowMenu.MenuItems.Add ( "水平平铺(&H)" , new EventHandler ( TileH_Click ) ) ;
WindowMenu.MenuItems.Add ( "垂直平铺(&V)" , new EventHandler ( TileV_Click ) ) ;
WindowMenu.MdiList = true ;
//这一句比较重要,有了这一句就可以实现在新建一个MDI窗体后会在此主菜单项下显示存在的MDI窗体菜单项
NewMenu = new MenuItem ( ) ;
NewMenu.Text = "新建窗体(&N)" ;
NewMenu.Click += new EventHandler ( New_Click ) ;
ExitMenu = new MenuItem ( ) ;
ExitMenu.Text = "退出(&X)" ;
ExitMenu.Click += new EventHandler ( Exit_Click ) ;
FileMenu.MenuItems.Add ( NewMenu ) ;
FileMenu.MenuItems.Add ( new MenuItem ( "-" ) ) ;
FileMenu.MenuItems.Add ( ExitMenu ) ;
mnuMain.MenuItems.Add ( FileMenu ) ;
mnuMain.MenuItems.Add ( WindowMenu ) ;
this.Menu = mnuMain ;
} private void Cascade_Click ( object sender , EventArgs e )
//实现对主窗体中的MDI窗体的层叠操作
{
this.LayoutMdi ( MdiLayout.Cascade ) ;
} private void TileH_Click ( object sender , EventArgs e )
//实现对主窗体中的MDI窗体的水平平铺操作
{
this.LayoutMdi ( MdiLayout.TileHorizontal ) ;
} private void TileV_Click ( object sender , EventArgs e )
//实现对主窗体中的MDI窗体的垂直平铺操作
{
this.LayoutMdi ( MdiLayout.TileVertical ) ;
} private void New_Click ( object sender , EventArgs e )
{
Form frmTemp = new Form ( ) ;
//新建一个窗体
frmTemp.MdiParent = this ;
//定义此窗体的父窗体,从而此窗体成为一个MDI窗体
frmTemp.Text = "窗体0" + FormCount.ToString ( ) ;
//设定MDI窗体的标题
FormCount++ ;
frmTemp.Show ( ) ;
//把此MDI窗体显示出来
} private void Exit_Click ( object sender , EventArgs e )
{
this.Dispose ( );
Application.Exit ( ) ;
} public static void Main ( )
{
Application.Run ( new MDIDemo ( ) ) ;
}
}
再经过以下编译命令编译过以后,就可以得到执行程序:
csc /t:winexe /r:system.dll /r:system.windows.forms.dll /r:system.drawing.dll mdi.cs
四.总结:
本文主要是介绍如何用Visual C#来实现对MDI窗体的编程。即:新建MDI窗体、MDI窗体层叠、MDI窗体水平平铺、MDI窗体的垂直平铺。通过上述介绍,可见,在Visual C#中处理MDI还是相当比较简单的。
不过说实现在我不建议大家这样实现了,而是喜欢使用Tabcontrol的方法,这样容易控件,而且可以达到多任务,多操作的效果,也是目前几乎所有浏览器都采用的方法
MDI窗体容器 - 放窗体的容器
窗体是顶级控件,是不允许放到其他的控件或窗体中的 (李献策lxc)
窗体属性中有一个属性:IsMdiContainer - 确定该窗体是否是MDI容器
在窗体中放一个顶部菜单
点击<销售>按钮会在窗体中弹出一个新的窗体
//销售
private void 销售ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form5 f5 = new Form5();
f5.MdiParent = this;
f5.Show();
}
内部窗体可以在父级窗体里任意移动
问题一:打开新的窗体全屏(李献策lxc)
//销售
private void 销售ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form5 f5 = new Form5();
//窗体最大化
f5.WindowState = FormWindowState.Maximized; f5.MdiParent = this;
f5.Show();
}
问题二:打开后有最小化、最大化等按钮
错误方法一:去掉最大化最小化按钮——失败
//销售
private void 销售ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form5 f5 = new Form5();
//窗体最大化
f5.WindowState = FormWindowState.Maximized; //去掉最大化最小化按钮
f5.MaximizeBox = false;
f5.MinimizeBox = false; f5.MdiParent = this;
f5.Show();
}
错误方法二:去掉边框——失败(李献策lxc)
//销售
private void 销售ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form5 f5 = new Form5();
//窗体最大化
f5.WindowState = FormWindowState.Maximized; //去掉边框
f5.FormBorderStyle = FormBorderStyle.None; f5.MdiParent = this;
f5.Show();
}
正确方法:先用一个panel填充窗体剩余部分,在panel中打开新窗体
//销售
private void 销售ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form5 f5 = new Form5();
//窗体最大化
f5.WindowState = FormWindowState.Maximized; //去掉边框
f5.FormBorderStyle = FormBorderStyle.None; f5.MdiParent = this; //设置新窗体的Parent
f5.Parent = panel1; f5.Show();
}
问题三:在即将打开的新窗体中放入一个button1,Anchor设置为Bottom,Right,当打开新窗体并拖动窗体边框时,按钮并未锁定与底部和右侧的距离
panel是跟随窗体的变化而变化,但是新窗体是不随panel变化而变化的
解决方法:设置主窗体的size发生改变时新窗体同时改变size(李献策lxc)
//Size改变时的事件
private void Form3_SizeChanged(object sender, EventArgs e)
{
//遍历panel中的控件,
foreach (var v in panel1.Controls)
{
//如果是新窗体
if (v is Form5)
{
//新窗体先变为正常大小
(v as Form5).WindowState = FormWindowState.Normal;
//新窗体再变为最大化以适应新的Size
(v as Form5).WindowState = FormWindowState.Maximized;
}
}
}
问题四:在点击<仓库>按钮时,会在主窗体中打开一个新的窗体,再点击<销售>按钮会切回销售窗体,但实际是又创建了一个新的销售窗体而已,并非原来打开的窗体
解决办法:唯一窗体(李献策lxc)
==========================================================
权限设置 - 不同的权限登入时显示内容不同
新建一个登入窗体
数据库中添加一个新的权限表
1、首先设置父级Form1界面,只需要将该界面的IsMdiContainer属性设置为true;
2、设置按钮的事件来打开子级的窗口Form2,Form3等等;
3、在From1内设置一个容器panel,范围为需要打开的子级界面的大小;
4、设置Form2、Form3的事件,以及唯一窗口等;
//Form2的点击事件
private void form2ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Name = "f2";
openwidow(f2);
}
//Form3的点击件
private void form3ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form3 f3 = new Form3();
f3.Name = "f3";
openwidow(f3);
}
//设置唯一窗口:
//新建一个formlist集合,供唯一窗口使用
List<Form> formlist = new List<Form>();
//新建一个public的方法
private void openwidow(Form f)
{
//定义一个Form fff变量
Form fff = null;
//定义一个bool类型的变量为false;
bool open = false;
//遍历这个集合
foreach (Form ff in listfrom)
{
//只要遍历到就隐藏
ff.Hide();
//如果遍历到f.name
if (ff.Name == f.Name)
{
open = true;
//把ff放到集合内
fff = ff;
}
}
//如果遍历到f.name,
if (open)
{
//关闭所有窗口
f.Close();
//重新打开这个串口
fff.Show();
}
//否则
else
{
//设置打开的窗口为Form1的子窗体;
f.MdiParent = this;
//设置子窗口的大小为最大化;
f.WindowState = FormWindowState.Maximized;
//把子窗口放到Form1的panel1里;
f.Parent = panel1;
//设置无边框
f.FormBorderStyle = FormBorderStyle.None;
//打开窗口
f.Show();
//把这个窗口放到集合内
fromlist.Add(f);
} }
2019-8-15C#MDI窗体实现多窗口效果的更多相关文章
- 使用MDI窗体实现多窗口效果
本文章已收录于: C#MDI窗体实现多窗口效果 Visual C#是微软公司推出的下一代主流程序开发语言,他也是一种功能十分强大的程 序设计语言,正在受到越来越多的编程人员的喜欢.在Visua ...
- MDI窗体 的再度思考
早在敲学生管理系统的时候,青山师哥就跟我说过 MDI 窗体 跟 子窗体的事情,当时只是简单的查询.小小的用了一下,没有太在意. 当再次面对着这个东西更深层的时候才想起师哥那句话.“好好研究一下这个东 ...
- 2015.12.14 MDI(多文档窗口结构)设置基本解决,折腾一天,部分解决存在已久的问题。但效果仍不如临时航线的MDI窗体结构。
创建从一个窗口弹出多个子窗口的结构叫MDI窗体结构 如果不按MDI结构管理,最简单的做法是: 在窗体A上添加菜单或按钮,在菜单或按钮事件中添加弹出B窗体代码: B b = new B(); b.sho ...
- MDI窗体容器--2016年12月15日
MDI窗体容器 多文档界面(Multiple-Document Interface)简称MDI窗体.MDI窗体用于同时显示多个文档,每个文档显示在各自的窗口中.MDI窗体中通常有包含子菜单的窗口菜单, ...
- 小菜学习Winform(四)MDI窗体(附示例)
前言 在做winfrom项目的时候我们可能会用到嵌套窗体,就是说一个容器中有多个窗体,可以分别管理和应用这些窗体,.net中提供了一种机制就是MDI,可能大家都会用,这边就简单的介绍下. 简单应用 w ...
- MDI窗体容器、权限设置
一.MDI窗体容器: 1.功能: 它可以让其它窗体在它的内部打开,无法超出它的范围 将某个窗体的属性:IsMdiContainer设置为true - 窗口样式 2.问题: (1)如何将其它窗体在它的内 ...
- MDI窗体容器 权限设置
MDI窗体容器:它可以让其它窗体在它的内部打开,无法超出它的范围将某个窗体的属性:IsMdiContainer设置为true - 窗口样式如何将其它窗体在它的内部打开?窗体对象名.MdiParent ...
- winform(MDI窗体容器、权限设置)
一.MDI窗体容器: 1.功能: 它可以让其它窗体在它的内部打开,无法超出它的范围 将某个窗体的属性:IsMdiContainer设置为true - 窗口样式 2.问题: (1)如何将其它窗体在它的内 ...
- vb.net详解MDI窗体操作方法
MDI窗体可以避免打开窗体的时候被无数个子窗体困扰,我将为大家一一的介绍一下vb.net中MDI窗体的操作方法 一.如何创建MDI窗体? 1.创建mdi主窗体 新建建立一个默认空白的Windows应用 ...
随机推荐
- 3D Experience — 产品协同研发平台
随着产品复杂程度的提升,市场竞争愈加激烈,基于模型的正向研发已经作为有效的应对手段被广泛接受.但研发流程中仍然存在复杂功能架构定义困难.多方案难以权衡.多系统难以联合仿真,仿真效率低,验证不充分等问题 ...
- Android加载大图到内存如何避免内存溢出?
加载大图怎么避免溢出实际做法就是对图像进行压缩,也是比较老的话题了,在最初做android时是经常会遇到的问题,而如今对于图片加载这一块都已经有很成熟稳定的三方库来弄它了,所以图片加载过大内存溢出的比 ...
- dt7.0自定义推送熊掌号功能插件
因要推送较早的数据,所以写了一个自定义推送熊掌号的功能插件,因我自己站点是新站,推送的数据较少,所以程序比较简单,算是初始版本,凑合着用吧. <?php /* 百度当天主动推送熊掌功能 作者:6 ...
- Mybatis-Generator逆向工程,简单策略
1.下载generator包 https://github.com/mybatis/generator/releases mybatis-generator-core-1.3.6.zip 官网下载即可 ...
- vue 传入一个对象的所有属性
- 深入剖析TOMCAT
理解tomcat之搭建简易http服务器 做过java web的同学都对tomcat非常熟悉.我们在使用tomcat带来的便利的同时,是否想过tomcat是如何工作的呢?tomcat本质是一个http ...
- TDOA 之 基站接收数据
基站主要 接收同步节点发来的同步信号,代码里定义为S信息. 以及标签节点发来的定位信号,代码中定义为T信号. 代码中使用中断以及帧过滤功能,对模块只接收自己关心设定好的信息,通过中断告知上层,而不是长 ...
- 遍历器Iterator--指针对象
一. 什么是遍历器 1. 遍历器对象(Iterator) 遍历器对象本质上是一个指针对象,该对象有一个next方法,调用next方法返回一个 含有value和done属性的对象{value: val/ ...
- Planet.Earth.II.EP05.2016
- 差分约束 4416 FFF 团卧底的后宫
/* 4416 FFF 团卧底的后宫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 你在某日收到了 FFF ...