MDI窗体的工具栏合并(ToolStrip Merging)的功能实现
来源:互联网 发布:jeep自由光 知乎 编辑:程序博客网 时间:2024/05/22 03:09
这个模型的大概构成是这样的:
1个MDI主窗体,1~n个MDI子窗体;
主窗体上一般会有1个主菜单栏,1~n个主工具栏;
子窗体设计时上可能有0~1个主菜单栏,0~1个主工具栏,运行时子窗体的菜单栏和工具栏都显示在主窗体上,与主窗体的菜单栏和工具栏合并。(实际上也许会有多个工具栏,但先简化为一个工具栏的模型,实现了一个工具栏的合并后,要实现多个工具栏合并也并非难事)。
对于菜单栏的合并,无论是传统的Windows API编程或者Window Forms,都已经完美地解决了,不再赘述。
工具栏合并的过程最好在子窗体的激活和关闭处理处理,一个容易想到的方法是写在子窗体的事件代码中,要么需在每一个子窗体的代码文件写上类似处理的代码,要么让所有子窗体继承自一个写好相关事件处理代码的窗体。前者显然不可取,后者在单根继承的时代,剥夺了子窗体从其它窗体继承的可能,也不是一个好办法。同时还有一个弊端是子窗体要访问主窗体的内容,耦合度太高。
最佳方案也自然而然地出来了,即在主窗体的MdiChildActivate事件中处理(不能望文生义以为仅仅是子窗体的激活会触发此事件,事实上子窗体的关闭也会触发此事件)。这个时候应该把主窗体从上一个子窗体合并来的工具栏内容清除掉(如果有的话),并将新激活的子窗体上的待合并的工具栏内容合并到主窗体的工具栏上(如果新激活的子窗体上无待合并的工具栏内容或者MdiChildActivate是关闭最后一个子窗体触发的时候则无此步)。为简化代码,假设子窗体的工具栏总是合并到主窗体工具栏的最后位置。
这时候,主窗体必须知道子窗体的工具栏的构成,完全解耦是不太可能的。一种办法是将子窗体的工具栏控件的作用范围设置为public, 我采取了另外一个办法,就是定义了一个接口,让需合并工具栏的子窗口实现这个接口即可。
接口代码如下:
1个MDI主窗体,1~n个MDI子窗体;
主窗体上一般会有1个主菜单栏,1~n个主工具栏;
子窗体设计时上可能有0~1个主菜单栏,0~1个主工具栏,运行时子窗体的菜单栏和工具栏都显示在主窗体上,与主窗体的菜单栏和工具栏合并。(实际上也许会有多个工具栏,但先简化为一个工具栏的模型,实现了一个工具栏的合并后,要实现多个工具栏合并也并非难事)。
对于菜单栏的合并,无论是传统的Windows API编程或者Window Forms,都已经完美地解决了,不再赘述。
工具栏合并的过程最好在子窗体的激活和关闭处理处理,一个容易想到的方法是写在子窗体的事件代码中,要么需在每一个子窗体的代码文件写上类似处理的代码,要么让所有子窗体继承自一个写好相关事件处理代码的窗体。前者显然不可取,后者在单根继承的时代,剥夺了子窗体从其它窗体继承的可能,也不是一个好办法。同时还有一个弊端是子窗体要访问主窗体的内容,耦合度太高。
最佳方案也自然而然地出来了,即在主窗体的MdiChildActivate事件中处理(不能望文生义以为仅仅是子窗体的激活会触发此事件,事实上子窗体的关闭也会触发此事件)。这个时候应该把主窗体从上一个子窗体合并来的工具栏内容清除掉(如果有的话),并将新激活的子窗体上的待合并的工具栏内容合并到主窗体的工具栏上(如果新激活的子窗体上无待合并的工具栏内容或者MdiChildActivate是关闭最后一个子窗体触发的时候则无此步)。为简化代码,假设子窗体的工具栏总是合并到主窗体工具栏的最后位置。
这时候,主窗体必须知道子窗体的工具栏的构成,完全解耦是不太可能的。一种办法是将子窗体的工具栏控件的作用范围设置为public, 我采取了另外一个办法,就是定义了一个接口,让需合并工具栏的子窗口实现这个接口即可。
接口代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace Osmanthus.WinForms
{
interface IToolStripMergableForm
{
ToolStrip MergedToolStrip
{
get;
}
}
}
让子窗体实现这个接口,所要写的代码也简单,只有一句,即:using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace Osmanthus.WinForms
{
interface IToolStripMergableForm
{
ToolStrip MergedToolStrip
{
get;
}
}
}
public ToolStrip MergedToolStrip
{
get { return this.toolStrip1; }
}
剩下的内容似乎理想当然地是写主窗体的MdiChildActivate事件处理代码,不过我想增加重用性,就把它写成了一个组件,以后只要把该组件拖放在MDI主窗体,并设置此组件MainToolStrip属性为主窗体的工具栏(其实也可以写成自动获取默认属性值,即主窗体上的最后一个ToolStrip控件),不需对再对主窗体写一行代码。这个部件的代码内容如下(其中为实现组件对Form的存取参照了Chris Sells的大作,我不知道是否有其它的更好办法):{
get { return this.toolStrip1; }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.ComponentModel.Design;
namespace Osmanthus.WinForms
{
class SdiToolStripMerger : Component, ISupportInitialize
{
private Form hostingForm;
private ToolStrip mainToolStrip;
private IToolStripMergableForm currentMdiChild = null;
private List<ToolStripItem> toolStripItemList = new List<ToolStripItem>();
public ToolStrip MainToolStrip
{
get { return mainToolStrip; }
set { mainToolStrip = value; }
}
[BrowsableAttribute(false)]
public Form HostingForm
{
get
{
if ((hostingForm == null) && this.DesignMode)
{
IDesignerHost designer = this.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (designer != null)
{
hostingForm = designer.RootComponent as Form;
}
}
return hostingForm;
}
set
{
hostingForm = value; //这里需要改进一下, 应该一旦设置了host form,就不能再修改.
}
}
#region ISupportInitialize Members
public void BeginInit()
{
}
public void EndInit()
{
if ((!DesignMode) && (hostingForm != null))
{
hostingForm.MdiChildActivate += new EventHandler(UpdateToolStrip);
};
}
#endregion
void UpdateToolStrip(object sender, EventArgs e)
{
//清除从上个激活子窗体合并来的工具栏内容
if (currentMdiChild != null)
{
foreach (ToolStripItem toolItem in toolStripItemList)
{
currentMdiChild.MergedToolStrip.Items.Add(toolItem);
}
toolStripItemList.Clear();
}
IToolStripMergableForm form = (IToolStripMergableForm)hostingForm.ActiveMdiChild;
//如当前激活的子窗体实现了 IToolStripMergableForm接口,则合并其工具栏内容
if (form != null)
{
currentMdiChild = form;
foreach (ToolStripItem toolItem in currentMdiChild.MergedToolStrip.Items)
{
toolStripItemList.Add(toolItem);
}
foreach (ToolStripItem toolItem in toolStripItemList)
{
mainToolStrip.Items.Add(toolItem);
}
}
else
{
currentMdiChild = null;
toolStripItemList.Clear();
}
}
}
}
2006/12/25 附记:今天早上发现了.net Framework 2.0新增加的一个类ToolStripManager,使用此类可以简化上述代码。
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.ComponentModel.Design;
namespace Osmanthus.WinForms
{
class SdiToolStripMerger : Component, ISupportInitialize
{
private Form hostingForm;
private ToolStrip mainToolStrip;
private IToolStripMergableForm currentMdiChild = null;
private List<ToolStripItem> toolStripItemList = new List<ToolStripItem>();
public ToolStrip MainToolStrip
{
get { return mainToolStrip; }
set { mainToolStrip = value; }
}
[BrowsableAttribute(false)]
public Form HostingForm
{
get
{
if ((hostingForm == null) && this.DesignMode)
{
IDesignerHost designer = this.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (designer != null)
{
hostingForm = designer.RootComponent as Form;
}
}
return hostingForm;
}
set
{
hostingForm = value; //这里需要改进一下, 应该一旦设置了host form,就不能再修改.
}
}
#region ISupportInitialize Members
public void BeginInit()
{
}
public void EndInit()
{
if ((!DesignMode) && (hostingForm != null))
{
hostingForm.MdiChildActivate += new EventHandler(UpdateToolStrip);
};
}
#endregion
void UpdateToolStrip(object sender, EventArgs e)
{
//清除从上个激活子窗体合并来的工具栏内容
if (currentMdiChild != null)
{
foreach (ToolStripItem toolItem in toolStripItemList)
{
currentMdiChild.MergedToolStrip.Items.Add(toolItem);
}
toolStripItemList.Clear();
}
IToolStripMergableForm form = (IToolStripMergableForm)hostingForm.ActiveMdiChild;
//如当前激活的子窗体实现了 IToolStripMergableForm接口,则合并其工具栏内容
if (form != null)
{
currentMdiChild = form;
foreach (ToolStripItem toolItem in currentMdiChild.MergedToolStrip.Items)
{
toolStripItemList.Add(toolItem);
}
foreach (ToolStripItem toolItem in toolStripItemList)
{
mainToolStrip.Items.Add(toolItem);
}
}
else
{
currentMdiChild = null;
toolStripItemList.Clear();
}
}
}
}
2006/12/25 附记:今天早上发现了.net Framework 2.0新增加的一个类ToolStripManager,使用此类可以简化上述代码。
- MDI窗体的工具栏合并(ToolStrip Merging)的功能实现
- MDI窗体的工具栏合并(ToolStrip Merging)的功能实现
- MDI窗体的工具栏合并(ToolStrip Merging)的功能实现
- c# Mdi中合并子窗体的工具栏到主窗体的工具栏中
- C# MDI窗体菜单合并工具栏
- WPF实现类似MDI子窗体的功能
- C# MDI窗体合并子窗体菜单和合并工具栏
- C# MDI窗体菜单合并子窗体工具栏
- mdi多层子窗体的实现
- [WPF]WPF实现MDI窗体的方法
- WPF实现MDI窗体的方法
- WPF MDI窗体的实现方法
- 使用WPF实现MDI窗体的方法
- C#:MDI子窗体最大化导致父窗体工具栏移动的问题解决
- [VB.NET]怎样实现MDI窗体菜单上的“窗口”菜单下面的功能
- MDI里(工具栏)按钮的隐藏、移动和保存备份(xml),子窗体的调用
- MDI的子窗体问题
- MDI窗体的优化---上
- 基于达芬奇平台的微波视频监控系统
- 写Form设计器尝试(四) 修改窗体上的控件属性
- 写Form设计器尝试(五) 让设计器使用自定义控件
- 视频解码器SAA7111在图像采集中的应用
- 写Form设计器尝试(六) 实现菜单命令
- MDI窗体的工具栏合并(ToolStrip Merging)的功能实现
- Spring下,使用BeanNameAutoProxyCreator来管理Transaction例子
- APE 2D引擎教程
- 邮件系统postfix安装与配置
- .NET 将类对象存到本地电脑
- 白名单 -- 会陆续更新
- Exchange2003升级Exchange2007
- C++中的指针的指针的含义。
- Chinahunter急招SAP外企职位