• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 在winform下实现左右布局多窗口界面的方法

在winform下实现左右布局多窗口界面的方法

作者:梦在旅途 字体:[增加 减小] 来源:互联网 时间:2017-05-28

梦在旅途 通过本文主要向大家介绍了winform界面布局,winform布局,winform布局控件,winform界面设计,winform界面库等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在web页面上我们可以通过frameset,iframe嵌套框架很容易实现各种导航+内容的布局界面,而在winform、WPF中实现其实也很容易,我这里就分享一个:在winform下实现左右布局多窗口界面。

我这里说的多窗口是指一个父窗口包含多个子窗口,在winform中实现这种效果很简单,即将某个窗口的IsMdiContainer设为true,然后将其它子窗口的MdiParent设为其父窗口对象即可,这样就完成了一个多窗口界面,效果如下:


点击NEW新打开一个窗口,其效果如下:


请看我上图红色标注的地方,Windows菜单项下面显示的是当前所有已打开的子窗口,点击某个菜单,即可快速切换到其它窗口,若关闭某个子窗口,与之相对应的菜单项也会自动被移除,实现这个功能也很简单,只需要将菜单的MdiWindowListItem属性设为需要显示活动窗口列表的菜单项即可,如:this.menuStrip1.MdiWindowListItem = this.windowsToolStripMenuItem;

上述示例完整的实现代码如下:

public partial class FormMdi : Form
{
private int formCount = 0;
public FormMdi()
{
InitializeComponent();
this.menuStrip1.MdiWindowListItem = this.windowsToolStripMenuItem;
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowChildForm<FormChild>();
}
private void ShowChildForm<TForm>() where TForm : Form, new()
{
TForm childForm = new TForm();
childForm.Name = "frm" + Guid.NewGuid().ToString("N");
childForm.Text = string.Format("Child Form -{0}", ++formCount);
childForm.MdiParent = this;
childForm.WindowState = FormWindowState.Maximized;
childForm.Show();
}
}
</div>

相信实现上面这部份功能一般用过winform的人都会操作,我这里就当是复习顺便给新手一个参考,同时也为下面要实现的左右布局功能做一个铺垫吧。

要实现左右布局,并且能够支持可动态调整左右占比的功能,非SplitContainer控件莫属了,如果不了解该控件用法请自行在网上查找相关资料,我这里就不作说明,如果要显示WINDOWS已打开的子窗口情况,同样也需要用到MenuStrip控件,

最终设计的主窗口(FormMain)效果如下:


我这里因为只是演示,所以菜单控件上我只添加了两个菜单项,分别为:WINDOWS,用于显示WINDOWS已打开的子窗口列表,NEW,用于打开一个子窗口;SplitContainer控件全部采用默认的,没有放置任何控件在其中,如果用在正式系统中,一般左边Panel1中会放置一个树形菜单,右边Panel2中保持空即可,因为这个是用来作为子窗口的容器。

控件层次结构如下图示:


界面设计好了,下面就实现最重要的两个功能。

第一个功能:在右边Panel2中显示子窗口,实现代码如下:

public FormMain()
{
this.IsMdiContainer = true;
}
private void ShowChildForm<TForm>() where TForm : Form, new()
{
TForm childForm = new TForm();
childForm.Name = "frm" + Guid.NewGuid().ToString("N");
childForm.Text = string.Format("Child Form -{0}", ++formCount);
childForm.MdiParent = this;
childForm.Parent = splitContainer1.Panel2;
childForm.WindowState = FormWindowState.Maximized;
childForm.Show();
}
</div>

简要说明:

1.在窗口构造函数中动态的将IsMdiContainer设为true,当然也可以设计视图中设置;

2.编写一个显示写子窗口的方法,方法中需注意的地方:childForm.MdiParent = this;childForm.Parent = splitContainer1.Panel2,意思是:将当前窗口作为子窗口的父窗口,同时将Panel2指定为子窗口的父对象,这样就能实现子窗口在Panel2中打开了。

第二个功能:在WINDOWS菜单项下显示已打开的子窗口列表,这里实现就没有像文章一开始介绍的那样简单,使用那个方法是无效的,需要我们来自行实现,稍微有点复杂,但如果明白其实现原理,也就简单明白了。

实现思路:当childForm加载到Panel2时,会触发Panel2.ControlAdded事件,当childForm被关闭时,会触发Panel2.ControlRemoved事件,我们可以统一订阅这两个事件,当childForm加载时,那么就在WINDOWS菜单项下增加一个菜单项,反之则移除该菜单项,实现代码如下:

this.splitContainer1.Panel2.ControlAdded += Panel2_ControlChanged;
this.splitContainer1.Panel2.ControlRemoved += Panel2_ControlChanged;
void Panel2_ControlChanged(object sender, ControlEventArgs e)
{
var frm = e.Control as Form;
string menuName = "menu_" + frm.Name;
bool exists = this.splitContainer1.Panel2.Controls.Contains(frm);
if (exists)
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
menuItem.Checked = true;
frm.BringToFront();
frm.Focus();
}
else
{
windowsToolStripMenuItem.DropDownItems.Add(new ToolStripMenuItem() { Text = frm.Text, Name = menuName, Tag = frm, Checked = true });
}
}
else
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
windowsToolStripMenuItem.DropDownItems.Remove(menuItem);
menuItem.Dispose();
}
}
}
private ToolStripMenuItem GetMenuItem(string menuName)
{
var menuItems = windowsToolStripMenuItem.DropDownItems.Cast<ToolStripMenuItem>();
menuItems.ToList().ForEach(m => m.Checked = false);
return menuItems.Where(m => m.Name == menuName).SingleOrDefault();
}
</div>

同时为了实现点击WINDOWS菜单项的子菜单能够快速切换子窗口,需要订阅WINDOWS菜单项的DropDownItemClicked事件,当然也可以为新增的子菜单项订阅Click事件,实现代码如下:

windowsToolStripMenuItem.DropDownItemClicked += windowsToolStripMenuItem_DropDownItemClicked;
void windowsToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
var menuItem = GetMenuItem(e.ClickedItem.Name);
menuItem.Checked = true;
var childForm = menuItem.Tag as Form;
childForm.BringToFront();
childForm.Focus();
}
private void CheckWindowsMenuItem(string menuName)
{
var menuItem = GetMenuItem(menuName);
if (menuItem != null)
{
menuItem.Checked = true;
}
} 
</div>

这样就基本实现了在WINDOWS菜单项下显示已打开的子窗口列表,并点击指定的菜单项能够切换当前活动的子窗口,但仍有一个不足的地方,那就是,当直接点击子窗口来切换当前活动窗口时(说白了就是当点击某个子窗口标题栏,该窗口就显示在其它所有的子窗口最前面),WINDOWS菜单项下的子菜单勾选项没有同步更新,一开始想到的是用Activated事件来进行处理,结果经测试发现有效,该Activated事件在点击子窗口标题栏时并不会被触发,所以只能换种方法,经过多次测试,发现当窗口从后面切换到前面时(称为Z顺序改变),子窗口就会发生重绘,从而触发Paint方法,我们可以订阅该事件,并进行处理,实现代码如下:

private string currentChildFormName = null; //记录当前活动子窗口名称
childForm.Paint += (s, e) => { 
var frm=s as Form;
if (!frm.Name.Equals(currentChildFormName) && this.splitContainer1.Panel2.Controls[0].Equals(frm)) //当容器中第一个控件就是当前的窗口,则表明该窗口处于所有窗口之上
{
CheckWindowsMenuItem("menu_" + frm.Name);
currentChildFormName = frm.Name;
}
}; 
</div>

最后贴出完整的实现代码:

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 WindowsFormsApplication1
{
public partial class FormMain : Form
{
private int formCount = 0;
private string currentChildFormName = null;
public FormMain()
{
InitializeComponent();
this.IsMdiContainer = true;
this.splitContainer1.Panel2.ControlAdded += Panel2_ControlChanged;
this.splitContainer1.Panel2.ControlRemoved += Panel2_ControlChanged;
windowsToolStripMenuItem.DropDownItemClicked += windowsToolStripMenuItem_DropDownItemClicked;
}
void windowsToolSt



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 在winform下实现左右布局多窗口界面的方法之续篇
  • 在winform下实现左右布局多窗口界面的方法
  • winform 使用Anchor属性进行界面布局的方法详解

相关文章

  • 2017-05-28c#扫描图片去黑边(扫描仪去黑边)
  • 2017-05-28c#并行任务多种优化方案分享(异步委托)
  • 2017-05-28C#中DataGridView常用操作实例小结
  • 2017-05-28c#实现数据库事务示例分享
  • 2017-05-28C#实现rar压缩与解压缩文件的方法
  • 2017-05-28详解C#编程中异常的创建和引发以及异常处理
  • 2017-05-28c#中虚函数的相关使用方法
  • 2017-05-28C#通过DataSet读写xml文件的方法
  • 2017-05-28C#判断程序是否是管理员权限运行的方法代码示例
  • 2017-05-28C#中Dictionary的作用及用法讲解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#将布尔类型转换成字节数组的方法
    • C#通过反射获取当前工程中所有窗体并打开的方法
    • C#检测pc光驱里是否插入了光盘的方法
    • c#使用nsoup解析html乱码解决方法分享 nsoup教程
    • 基于C#生成随机数示例
    • WinForm特效之桌面上的遮罩层实现方法
    • Windows中使用C#为文件夹和文件编写密码锁的示例分享
    • C#使用linq计算执行元素在列表中出现次数的方法
    • WinForm中KeyDown,KeyPress和KeyUp的顺序与区别解析
    • C#如何实现图片查看器

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有