C# ToolStrip浮动及上/下/左/右 停靠

关于浮动工具条的制作,阿捷写了一篇很不错的文章,见:http://www.cnblogs.com/ajiefj/archive/2010/04/27/1722256.html
阿捷这个工具条浮动后只能在顶部停靠,基于此,我在这边增加在左/右/底部停靠,停靠条件是浮动窗体紧贴或越过主窗体边缘。

其实阿捷给出的代码已经相当详细了:) 我这里主要给出重写的ToolStrip代码段,增加了三个ToolStripPanel

    public partial class MyToolStrip : ToolStrip
    {
        public MyToolStrip()
        {
            InitializeComponent();
            this.EndDrag += new EventHandler(MyToolStrip_EndDrag);
            this.SizeChanged += new EventHandler(MyToolStrip_SizeChanged);
        }

        #region 漂浮状态

        public ToolStripFloatWindow FloatWindow { get; set; }

        private bool isFloating
        {
            get
            {
                return (FloatWindow != null);
            }
        }

        public ToolStripPanel TopToolStripPanel { get; set; }
        public ToolStripPanel BottomToolStripPanel { get; set; }
        public ToolStripPanel LeftToolStripPanel { get; set; }
        public ToolStripPanel RightToolStripPanel { get; set; }

        #endregion

        #region 漂浮实现

        private void FloatWindow_LocationChanged(object sender, EventArgs e)
        {
            //当floatwindws的位置移动到 toolstrippanel中时,将this放置到 toolstripPanel上
            if (this.FloatWindow == null)
            {
                return;
            }
            if (FloatWindow.HasCreated)
            {
                //主窗体位置
                Point frmLoc = this.TopToolStripPanel.Parent.Location;
                //浮动工具条位置
                Point toolBarLoc = FloatWindow.Location;

                if (toolBarLoc.Y - frmLoc.Y <= 0) //置于顶部StripPanel
                {
                    this.FloatWindow.Controls.Remove(this);
                    this.TopToolStripPanel.SuspendLayout();
                    this.TopToolStripPanel.Controls.Add(this);
                    this.Location = this.TopToolStripPanel.PointToClient(toolBarLoc);
                    this.TopToolStripPanel.ResumeLayout();
                    this.FloatWindow.Dispose();
                    this.FloatWindow = null;
                    return;
                }
                if (toolBarLoc.X - frmLoc.X <= 0) //置于左边StripPanel
                {
                    this.FloatWindow.Controls.Remove(this);
                    this.LeftToolStripPanel.SuspendLayout();
                    this.LeftToolStripPanel.Controls.Add(this);
                    this.Location = this.LeftToolStripPanel.PointToClient(toolBarLoc);
                    this.LeftToolStripPanel.ResumeLayout();
                    this.FloatWindow.Dispose();
                    this.FloatWindow = null;
                    return;
                }
                if (toolBarLoc.X + FloatWindow.Width >= this.TopToolStripPanel.Parent.Width) //置于右边StripPanel
                {
                    this.FloatWindow.Controls.Remove(this);
                    this.RightToolStripPanel.SuspendLayout();
                    this.RightToolStripPanel.Controls.Add(this);
                    this.Location = this.RightToolStripPanel.PointToClient(toolBarLoc);
                    this.RightToolStripPanel.ResumeLayout();
                    this.FloatWindow.Dispose();
                    this.FloatWindow = null;
                    return;
                }
                if (toolBarLoc.Y + FloatWindow.Height >= this.TopToolStripPanel.Parent.Height) //置于底部StripPanel
                {
                    this.FloatWindow.Controls.Remove(this);
                    this.BottomToolStripPanel.SuspendLayout();
                    this.BottomToolStripPanel.Controls.Add(this);
                    this.Location = this.BottomToolStripPanel.PointToClient(toolBarLoc);
                    this.BottomToolStripPanel.ResumeLayout();
                    this.FloatWindow.Dispose();
                    this.FloatWindow = null;
                    return;
                }
            }
        }

        private void MyToolStrip_EndDrag(object sender, EventArgs e)
        {
            Point screenPt = Cursor.Position;
            Point clientPt = this.TopToolStripPanel.Parent.PointToClient(screenPt);

            //浮动区域
            Rectangle floatArea = new Rectangle(32, 32,    //我这里图标大小调整为32*32
                this.TopToolStripPanel.Parent.Width - 2 * 32, 
                this.TopToolStripPanel.Parent.Height - 2 * 32);

            if (floatArea.Contains(clientPt)) //判断移出时
            {
                ToolStripFloatWindow fw = new ToolStripFloatWindow();
                fw.Controls.Add(this);
                this.Left = 0;
                this.Top = 0;
                this.FloatWindow = fw;
                FloatWindow.LocationChanged += new EventHandler(FloatWindow_LocationChanged);
                fw.SetBounds(screenPt.X, screenPt.Y, this.ClientSize.Width, this.ClientSize.Height + 22); //22为窗体标题栏高度
                  fw.Show();
             }
        }

        private void MyToolStrip_SizeChanged(object sender, EventArgs e)
        {
            if (this.isFloating)
            {
                this.FloatWindow.Width = this.ClientSize.Width;
            }
        }

        #endregion

    }


主窗体自然是放四个ToolStripPanel和一个MyToolStrip,注意主窗体的IsMdiContainer属性 置为 True

tooltrip漂浮(在toolstrippanel和之外) 具体设计思想如下: 放置到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类。增加了相应的属性和方法。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值