MDI窗体的工具栏合并(ToolStrip Merging)的功能实现

转载 2008年07月18日 15:04:00
这个模型的大概构成是这样的:
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;
        }
    }
}
让子窗体实现这个接口,所要写的代码也简单,只有一句,即:
public ToolStrip MergedToolStrip
{
    
get { return this.toolStrip1; }
}
剩下的内容似乎理想当然地是写主窗体的MdiChildActivate事件处理代码,不过我想增加重用性,就把它写成了一个组件,以后只要把该组件拖放在MDI主窗体,并设置此组件MainToolStrip属性为主窗体的工具栏(其实也可以写成自动获取默认属性值,即主窗体上的最后一个ToolStrip控件),不需对再对主窗体写一行代码。这个部件的代码内容如下(其中为实现组件对Form的存取参照了Chris Sells的大作,我不知道是否有其它的更好办法):
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,使用此类可以简化上述代码。

C# MDI窗体合并子窗体菜单和合并工具栏

 C# MDI窗体菜单合并子窗体菜单非常简单,只需设置一下属性AllowMerge=True就OK;但要合并工具栏,就稍微复杂一下了。 C# MDI窗体工具栏合并子窗体工具栏 第一,MDI窗体代码:/...
  • LRG315
  • LRG315
  • 2008年01月11日 00:38
  • 6599

WinForm自动菜单合并

周克的技术BlogWinForm自动菜单合并 通过将 MDI 父窗体的 IsMdiContainer 属性设置为 true 来创建 MDI 父窗体。 向 MDI 父窗体添加 MenuStrip,将其 ...
  • xbgprogrammer
  • xbgprogrammer
  • 2010年01月15日 16:59
  • 993

C#工具栏合并问题

当使用MDI技术时,为了美观或者什么原因可能需要合并工具栏。方法如下(http://blog.csdn.net/zyc21st/archive/2007/04/21/1573921.aspx):在MD...
  • kudoran
  • kudoran
  • 2010年04月15日 11:02
  • 955

MDI窗体的工具栏合并(ToolStrip Merging)的功能实现

在MDI窗体定义        public interface ICipherInputForm        {            ToolStrip CipherToolStrip     ...
  • zyc21st
  • zyc21st
  • 2007年04月21日 18:28
  • 801

MDI窗体的工具栏合并(ToolStrip Merging)的功能实现

在MDI窗体定义        public interface ICipherInputForm        {            ToolStrip CipherToolStrip     ...
  • guanshenglang
  • guanshenglang
  • 2007年02月07日 11:07
  • 2308

WPF读写excel的完整示例-excel文件合并工具

using System.Data;using System.Data.OleDb;using System.IO;using System.Text;using System.Windows;nam...
  • dotfun
  • dotfun
  • 2011年05月12日 10:18
  • 4779

WPF Style & Template

WPF元素可以使用一个样式,通过元素的Style属性设置(Style属性在FrameworkElement中定义) Setter是Style中最重要的属性,Setter只支持依赖属性; 某些依赖属...
  • hetoby
  • hetoby
  • 2017年09月22日 13:46
  • 159

toolStripContainer在mdi窗体中遮蔽mdi子窗体的解决办法

toolStripContainer在父窗体停靠以后会遮蔽mdi的子窗体在toolStripContainer.ContentPanel上面放panel,然后pannel设置在父窗体中停靠在show窗...
  • atlasroben
  • atlasroben
  • 2008年07月28日 13:43
  • 3932

如何在MDI程序中把子窗体菜单合并到主窗体上

       这里只讲在MDI中,子菜单与父菜单合并的简单方法。 首先在MDI的主窗体中:1.  在主窗体构造函数中,添加如下代码,注意要在InitializeComponent调用之后,如:    ...
  • Knight94
  • Knight94
  • 2006年03月16日 16:00
  • 8554

VS2012(InstallShield2015LimitedEdition)打包程序详解

VS2012没有自带打包工具,所以要先下载并安装一个打包工具。我采用微软提供的打包工具:  InstallShield2015LimitedEdition。下载地址:https://msdn.micr...
  • caiandyong
  • caiandyong
  • 2016年01月26日 15:01
  • 26358
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MDI窗体的工具栏合并(ToolStrip Merging)的功能实现
举报原因:
原因补充:

(最多只允许输入30个字)