您的位置:首页 > 编程语言 > C#

Visual C# .Net 环境中编程实现浮动工具栏

2013-12-16 13:33 477 查看
    Visual C# .Net 环境中编程实现浮动工具栏
                               郭胜涛
mailtogst@163.com

        DotNet2.0开发框架中提供的ToolStrip和ToolStripPanel控件可以方便开发具有可停靠工具栏功能的Windows应用程序, ToolStrip对象可以在各个ToolStripPanel间完成拖拽停靠,但是如果想实现类似VS IDE 或Office中可以浮动的工具栏必须借助于DevExpress等一些第三方的控件或编写一定的代码。 这里介绍一种比较简单的方法,只需继承ToolStrip类即可实现上述的效果。

        基本思路,我们可以从需求中作这样的假设,工具栏最开始时是放置到ToolStripPanel上的, 当工具栏浮动的时候,事实上是改变了其所在的容器对象,从其所在的ToolStripPanel移动到一个漂浮的容器上,因此要实现工具栏的浮动必须解决以下两个问题:

 必须有一个浮动的容器来承载ToolStrip对象。
 必须知道ToolStrip对象何时改变其所在的容器, 即在浮动的容器和主窗口上ToolStripPanel之间停靠。

       对于第一个问题,我们的解决方案是动态的创建一个Form类作为浮动的容器,命名为ToolStripFloatWindow,该Form对象具有以下的属性:

FormBorderStyle = FixedToolWindow   边框样式

ShowInTaskbar = false 不在任务栏显示

ShowIcon = false  不显示窗口图标

TopMost = true  在所有窗口之上

        为了解决第二个问题,我们查阅MSDN获知,当用鼠标拖拽ToolStrip对象释放鼠标时会触发其EndDrag事件。 我们在这个事件的处理方法中判断当ToolStrip对象的位置被移动到所在的ToolStripPanel之外的时候,创建ToolStripFloatWindow对象,并将ToolStrip对象移动到ToolStripFloatWindow上;要使ToolStrip对象恢复到原来的窗体上只要判断ToolStripFloatWindow对象的位置是否移动到了ToolStripPanel上,
当条件满足时将ToolStrip对象移动回ToolStripPanel中并销毁ToolStripFloatWindow对象。

此外,还要解决当ToolStrip对象放置到ToolStripFloatWindow对象上时, ToolStripFloatWindow对象必须与ToolStrip对象的尺寸一致。 还有ToolStripFloatWindow对象被点击了关闭按钮时不能将自己关闭。

我们可以做两个类来实现上述的思路。如图:



 

     ToolStripFloatWindow类继承自Form类。

     MyToolStrip 继承自ToolStrip类。增加了相应的属性和方法。

    MyToolStrip类的源代码如下:

 


using System;


using System.Collections.Generic;


using System.ComponentModel;


using System.Data;


using System.Drawing;


using System.Text;


using System.Windows.Forms;


using System.Runtime.InteropServices;




namespace FloatingToolStrip




...{


    public partial class MyToolStrip : ToolStrip




    ...{


        public MyToolStrip()




        ...{


            InitializeComponent();


            this.EndDrag += new EventHandler(MyToolStrip_EndDrag);


            this.SizeChanged += new EventHandler(MyToolStrip_SizeChanged);


        }




        protected override void OnPaint(PaintEventArgs pe)




        ...{


            // TODO: 在此处添加自定义绘制代码




            // 调用基类 OnPaint


            base.OnPaint(pe);


        }






        漂浮状态#region 漂浮状态




        private ToolStripFloatWindow floatWindow;




        public ToolStripFloatWindow FloatWindow




        ...{


            get




            ...{


                return this.floatWindow;


            }


            set




            ...{


                floatWindow = value;


                if (FloatWindow != null)




                ...{


                    floatWindow.LocationChanged += new EventHandler(floatWindow_LocationChanged);


                    floatWindow.FormClosing += new FormClosingEventHandler(floatWindow_FormClosing);   


                }


            }


        }




        public bool isFloating




        ...{


            get




            ...{


                return (floatWindow != null);


            }


        }




        private ToolStripPanel tsPanel;




        public ToolStripPanel ToolStripPanel




        ...{


            get




            ...{


                return this.tsPanel;


            }


            set




            ...{


                tsPanel = value;


            }


        }




        #endregion






        漂浮实现#region 漂浮实现




        private void floatWindow_LocationChanged(object sender, EventArgs e)




        ...{


            //当floatwindws的位置移动到 toolstrippanel中时,将this放置到 toolstripPanel上


            if (this.floatWindow == null)




            ...{


                return;


            }


            Point currentPt = new Point(floatWindow.Location.X, floatWindow.Location.Y);


            Point minpt = this.tsPanel.PointToScreen(tsPanel.Location);


            Point maxpt;




            if(this.tsPanel.Height <= 20)...{


                maxpt = new Point(minpt.X + this.tsPanel.Width, minpt.Y + 20);




            }else...{


                maxpt = new Point(minpt.X + this.tsPanel.Width, minpt.Y + this.tsPanel.Height);


            }




            if ((currentPt.X > minpt.X) && (currentPt.X < maxpt.X) && (currentPt.Y > minpt.Y) && (currentPt.Y < maxpt.Y))




            ...{


                this.floatWindow.Controls.Remove(this);


                this.tsPanel.SuspendLayout();


                this.tsPanel.Controls.Add(this);


                this.Location = this.tsPanel.PointToClient(currentPt);


                this.tsPanel.ResumeLayout();


                this.floatWindow.Dispose();


                this.floatWindow = null;


          


            } 


        }




        private void MyToolStrip_EndDrag(object sender, EventArgs e)




        ...{


            //判断移出时


            if (this.tsPanel == null)




            ...{


                MessageBox.Show("请先设置ToolStripPanel属性");


                return;


            }


            Point endPoint = Cursor.Position;          


            int openX, openY;


            openX = endPoint.X;


            openY = endPoint.Y;


            Point clientPt = this.tsPanel.Parent.PointToClient(endPoint);


            if (clientPt.Y > tsPanel.Height)




            ...{


                ToolStripFloatWindow fw = new ToolStripFloatWindow();


                this.tsPanel.Controls.Remove(this);


                fw.Controls.Add(this);


                this.Left = 0;


                this.Top = 0;


                this.FloatWindow = fw;


                Point newLoc = new Point(openX, openY);


                fw.Show();


                fw.Location = newLoc;


                fw.SetBounds(newLoc.X, newLoc.Y, this.ClientSize.Width, this.ClientSize.Height);


            }


        }




        private void floatWindow_FormClosing(object sender, FormClosingEventArgs e)




        ...{


            e.Cancel = true;


        }




        private void MyToolStrip_SizeChanged(object sender, EventArgs e)




        ...{


            if (this.isFloating)




            ...{


                this.floatWindow.Width = this.ClientSize.Width;


            }


        }




        #endregion




    }


}



 

    结论。 该方法实现较简单, 当不愿意使用功能较强大的第三方控件库时可以采用这种方法,缺点是负责浮动的容器是一个窗口,不大美观。

运行效果如下:



 另附送完整源代码:将地址拷贝到ie地址栏或Flashget下载

 http://dl2.csdn.net/down4/20070824/24152849181.rar (已失效)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: