在伍华聪的博客中,看到布局控件"WeifenLuo.WinFormsUI.Docking",发现的确是一个非常棒的开源控件,用过的人都深有体会,该控件之强大、美观、不亚于商业控件。而且控件使用也是比较简单的今天在这里,我想与大家一起分这一伟大的控件。有兴趣的同学,可以一同探讨与学习一下,否则就略过吧。

 

 

 

一、引用方法:

 

1.建立一个WinForm工程,默认生成了一个WinForm窗体。

 

2.引用—>添加引用—>浏览—>weiFenLuo.winFormsUI.Docking.dll。

 

3.窗体属性IsMdiContainer:True。

 

4.工具箱—>右键—>选择项—>.net组件—>浏览—>weiFenLuo.winFormsUI.Docking.dll—>在工具箱出现dockPanel。

WeifenLuo.WinFormsUI.Docking_winform 

 

 

 

5.将dockPanel拖到窗体上,设置Dock属性,我设置的是:Fill。在这里要注意,在先增加菜单工具条,后增加dockpanel否则,会出现布局介面显示不全的问题。

WeifenLuo.WinFormsUI.Docking_winform_02 

以下为具体的设计介面:

WeifenLuo.WinFormsUI.Docking_winform_03 

左侧加入一窗体,并设计成outlookbar的样式。它其实也是在一个停靠的窗体中的,继承自WeifenLuo.WinFormsUI.Docking.DockContent

WeifenLuo.WinFormsUI.Docking_C#_04

二、加入其它两个控件配合介面的设计:(UtilityLibrary+ IrisSkin2)

UtilityLibrary.dll为可以产生outlookbar这样的效果

 

IrisSkin2.dll为引入皮肤控件

三.设计完成后的介面如下:

WeifenLuo.WinFormsUI.Docking_C#_05

四.其它部分就是代码部分:



WeifenLuo.WinFormsUI.Docking_开源_06


1.frmmain.cs部分:

private string m_strConfigFile;

        private DeserializeDockContent m_deserializeDockContent;

        public frmMain()

        {

            InitializeComponent();

            InitializeLeftBar();

        }

        private void InitializeLeftBar()

        {

            m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);

            frmTemp = this;

            m_strConfigFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "DockPanel.config");

            m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);

        }

        private IDockContent GetContentFromPersistString(string persistString)

        {

            if (persistString == typeof(frmLeftBar).ToString())

            {

                return frmLeftBar;

            }

            else

            {

                // 可以加的其它子窗体

                return null;

            }

        }


2.加载主窗口

private void frmMain_Load(object sender, EventArgs e)

        {

            globalcolor = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue("config.xml", "Color", "UserColor")));

            globalcolor2 = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue("config.xml", "Color", "IMColor")));

            CreditControl = Convert.ToBoolean(C_BaseInfo.GetsysConf().Tables[0].Rows[0]["CreditControl"]);

            //设置时间和日期

            tssl1.Text = "今天日期:" + DateTime.Now.ToString("yyyy-MM-dd");

            tssl2.Text = "登录时间:" + System.DateTime.Now.ToLongTimeString();

            tsslLoginUser.Text = "当前用户:" + " " + frmLogin.C_UserInfo.SysUser;

            MenuStrip ms = (MenuStrip)this.Controls["menuStrip1"];

            ArrayList arr = new ArrayList();

            dsright = C_BaseInfo.UserRight(frmLogin.C_UserInfo);

            GetMenuAllName(arr, null, 0, ms);//调用递归函数

            if (File.Exists(m_strConfigFile))

            {

                dockPanel1.LoadFromXml(m_strConfigFile, m_deserializeDockContent);

            }

            frmLeftBar.Show(this.dockPanel1, DockState.DockLeft);

            this.dockPanel1.BackgroundImage = global::ECM.Properties.Resources.cable_16_92;





        }

3.显示子窗口

private ECM.Purchase.frmPO frmpo = null;

        private void mnuPO_Click(object sender, EventArgs e)

        {

            if (FindFormName("frmPO") == null)

            {

                frmpo = new ECM.Purchase.frmPO(this);


            

            frmpo.MdiParent = this;

            frmpo.Show(frmMain.frmTemp.dockPanel1);

            frmpo.Focus();

            }

            else

            {

                Form f = FindFormName("frmPO") as Form;

                f.Focus();

            }


        }


WeifenLuo.WinFormsUI.Docking_开源_06


 

 WeifenLuo.WinFormsUI.Docking_控件_08

 

以下为其它同学编写有关该控件的技术文档,供大家参考

 

1. 在浏览网上的一些技术文章发现,的确有些地方还是可以进一步改进,如当双击Tab时,原先是直接把当前Tab所表示的这个窗体,从主窗体的框架上分离现来,成为一个浮动的窗体。这不是我们想要的,有些同学修改源代码,把它改成了双击关闭。(测试Ok)

 

以下链接为官方共享代码的出处,大家可以利用svn下载到最新的代码。所有的修改全部建立在源代码基础上的

 

双击关闭标签代码 主要是修改 DockPaneStripBase.cs 类里的protected override void WndProc(ref Message m)函数 代码如下

 

在DockPaneStripBase.cs 的WndProc方法里,对于左键双击消息重新作了处理(下面注释掉的一行是原先的写法,它下面那行是改的):



WeifenLuo.WinFormsUI.Docking_开源_06

 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]

        protected override void WndProc(ref Message m)

        {

            if (m.Msg == (int)Win32.Msgs.WM_LBUTTONDBLCLK)

            {

                base.WndProc(ref m);

                int index = HitTest();

                if (DockPane.DockPanel.AllowEndUserDocking && index != -1)

                {

                    IDockContent content = Tabs[index].Content;

                    //if (content.DockHandler.CheckDockState(!content.DockHandler.IsFloat) != DockState.Unknown)

                        //content.DockHandler.IsFloat = !content.DockHandler.IsFloat; //这句表示窗口还原初始大小并且脱离任何停靠

                    if (content.DockHandler.HideOnClose)

                        content.DockHandler.Hide();//隐藏

                    else

                        content.DockHandler.Close(); //关闭        

                }

 

                return;

            }

            base.WndProc(ref m);

            return;

WeifenLuo.WinFormsUI.Docking_开源_06


        } 

2、很多窗体都在Tab中有个右键菜单,右击的里面有关闭,所以最好继承一下DockContent,让其它窗体只要继承这个就有了这个右键菜单,在里面加入ContextMenuStrip菜单工具并加入关闭全部关闭除此之外全部关闭三个菜单(这个我是从网上其它网友处复制出来的,未作测试)



WeifenLuo.WinFormsUI.Docking_开源_06

/// <summary>

    /// 很多窗体都在Tab中有个右键菜单,右击的里面有关闭,所以最好继承一下DockContent,

    /// 让其它窗体只要继承这个就有了这个右键菜单

    /// </summary>

    public class DockContentEx : DockContent

    {

        //在标签上点击右键显示关闭菜单

        public DockContentEx( )

        {

            System.Windows.Forms.ContextMenuStrip cms = new System.Windows.Forms.ContextMenuStrip();

            // 

            // tsmiClose

            // 

            System.Windows.Forms.ToolStripMenuItem tsmiClose = new System.Windows.Forms.ToolStripMenuItem();

            tsmiClose.Name = "cms";

            tsmiClose.Size = new System.Drawing.Size(98, 22);

            tsmiClose.Text = "关闭";

            tsmiClose.Click += new System.EventHandler(this.tsmiClose_Click);

            // 

            // tsmiALLClose

            // 

            System.Windows.Forms.ToolStripMenuItem tsmiALLClose = new System.Windows.Forms.ToolStripMenuItem();

            tsmiALLClose.Name = "cms";

            tsmiALLClose.Size = new System.Drawing.Size(98, 22);

            tsmiALLClose.Text = "全部关闭";

            tsmiALLClose.Click += new System.EventHandler(this.tsmiALLClose_Click);

            // 

            // tsmiApartFromClose

            // 

            System.Windows.Forms.ToolStripMenuItem tsmiApartFromClose = new System.Windows.Forms.ToolStripMenuItem();

            tsmiApartFromClose.Name = "cms";

            tsmiApartFromClose.Size = new System.Drawing.Size(98, 22);

            tsmiApartFromClose.Text = "除此之外全部关闭";

            tsmiApartFromClose.Click += new System.EventHandler(this.tsmiApartFromClose_Click);

            // 

            // tsmiClose

            // 

            cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

            tsmiClose,tsmiApartFromClose,tsmiALLClose});

            cms.Name = "tsmiClose";

            cms.Size = new System.Drawing.Size(99, 26);

            this.TabPageContextMenuStrip = cms;

        }

        private void tsmiClose_Click(object sender, EventArgs e)

        {

            this.Close();

        }

        private void tsmiALLClose_Click(object sender, EventArgs e)

        {

            DockContentCollection contents = DockPanel.Contents;

            int num = 0;

            while (num < contents.Count)

            {

                if (contents[num].DockHandler.DockState == DockState.Document)

                {

                    contents[num].DockHandler.Hide();

                }

                else

                {

                    num++;

                }

            }

        }

        private void tsmiApartFromClose_Click(object sender, EventArgs e)

        {

            DockContentCollection contents = DockPanel.Contents;

            int num = 0;

            while (num < contents.Count)

            {

                if (contents[num].DockHandler.DockState == DockState.Document && DockPanel.ActiveContent != contents[num])

                {

                    contents[num].DockHandler.Hide();

                }

                else

                {

                    num++;

                }

            }

        }

WeifenLuo.WinFormsUI.Docking_开源_06


}

以下为其它同学编写有关该控件的技术文档,供大家参考

 

以下是修改后的dll供大家下载:

在伍华聪的博客中,看到布局控件"WeifenLuo.WinFormsUI.Docking",发现的确是一个非常棒的开源控件,用过的人都深有体会,该控件之强大、美观、不亚于商业控件。而且控件使用也是比较简单的今天在这里,我想与大家一起分这一伟大的控件。有兴趣的同学,可以一同探讨与学习一下,否则就略过吧。

 

一、引用方法:

1.建立一个WinForm工程,默认生成了一个WinForm窗体。

2.引用—>添加引用—>浏览—>weiFenLuo.winFormsUI.Docking.dll。

3.窗体属性IsMdiContainer:True。

4.工具箱—>右键—>选择项—>.net组件—>浏览—>weiFenLuo.winFormsUI.Docking.dll—>在工具箱出现dockPanel。

WeifenLuo.WinFormsUI.Docking_winform 

 

5.将dockPanel拖到窗体上,设置Dock属性,我设置的是:Fill。在这里要注意,在先增加菜单工具条,后增加dockpanel否则,会出现布局介面显示不全的问题。

WeifenLuo.WinFormsUI.Docking_winform_02 

以下为具体的设计介面:

WeifenLuo.WinFormsUI.Docking_winform_03 

左侧加入一窗体,并设计成outlookbar的样式。它其实也是在一个停靠的窗体中的,继承自WeifenLuo.WinFormsUI.Docking.DockContent

WeifenLuo.WinFormsUI.Docking_C#_04

二、加入其它两个控件配合介面的设计:(UtilityLibrary+IrisSkin2)

UtilityLibrary.dll为可以产生outlookbar这样的效果

IrisSkin2.dll为引入皮肤控件

三.设计完成后的介面如下:

WeifenLuo.WinFormsUI.Docking_C#_05

四.其它部分就是代码部分:



WeifenLuo.WinFormsUI.Docking_开源_06


1.frmmain.cs部分:

private string m_strConfigFile;

        private DeserializeDockContent m_deserializeDockContent;

        public frmMain()

        {

            InitializeComponent();

            InitializeLeftBar();

        }

        private void InitializeLeftBar()

        {

            m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);

            frmTemp = this;

            m_strConfigFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "DockPanel.config");

            m_deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);

        }

        private IDockContent GetContentFromPersistString(string persistString)

        {

            if (persistString == typeof(frmLeftBar).ToString())

            {

                return frmLeftBar;

            }

            else

            {

                // 可以加的其它子窗体

                return null;

            }

        }


2.加载主窗口

private void frmMain_Load(object sender, EventArgs e)

        {

            globalcolor = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue("config.xml", "Color", "UserColor")));

            globalcolor2 = System.Drawing.Color.FromArgb(Convert.ToInt32(W1.LoadXmlFileValue("config.xml", "Color", "IMColor")));

            CreditControl = Convert.ToBoolean(C_BaseInfo.GetsysConf().Tables[0].Rows[0]["CreditControl"]);

            //设置时间和日期

            tssl1.Text = "今天日期:" + DateTime.Now.ToString("yyyy-MM-dd");

            tssl2.Text = "登录时间:" + System.DateTime.Now.ToLongTimeString();

            tsslLoginUser.Text = "当前用户:" + " " + frmLogin.C_UserInfo.SysUser;

            MenuStrip ms = (MenuStrip)this.Controls["menuStrip1"];

            ArrayList arr = new ArrayList();

            dsright = C_BaseInfo.UserRight(frmLogin.C_UserInfo);

            GetMenuAllName(arr, null, 0, ms);//调用递归函数

            if (File.Exists(m_strConfigFile))

            {

                dockPanel1.LoadFromXml(m_strConfigFile, m_deserializeDockContent);

            }

            frmLeftBar.Show(this.dockPanel1, DockState.DockLeft);

            this.dockPanel1.BackgroundImage = global::ECM.Properties.Resources.cable_16_92;





        }

3.显示子窗口

private ECM.Purchase.frmPO frmpo = null;

        private void mnuPO_Click(object sender, EventArgs e)

        {

            if (FindFormName("frmPO") == null)

            {

                frmpo = new ECM.Purchase.frmPO(this);


            

            frmpo.MdiParent = this;

            frmpo.Show(frmMain.frmTemp.dockPanel1);

            frmpo.Focus();

            }

            else

            {

                Form f = FindFormName("frmPO") as Form;

                f.Focus();

            }


        }


WeifenLuo.WinFormsUI.Docking_开源_06


 

 WeifenLuo.WinFormsUI.Docking_控件_08

 

以下为其它同学编写有关该控件的技术文档,供大家参考