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

如何创建C#版浮动工具栏?

2013-12-16 09:46 369 查看
所谓的浮动工具栏,效果图如下:







也就是说,可以将工具栏拖出其原先的停靠位置,而且可以将拖出来的工具栏再拖放回去。

实现的基本思路如下

1、拖动出来以后,需要创建一个大小合适的窗口,作为工具栏新的停靠容器,这个窗口可以这样设置:

FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;

ShowIcon = false;

ShowInTaskbar = false;

TopMost = true;

2、浮动工具栏可以扩展自.Net Framework提供的ToolStrip,它被拖动都某个位置,松开鼠标左键时,会触发EndDarg事件,在这个事件中,我们将其从原来的停靠容器中移除,同时根据鼠标左键松开时,在鼠标所在位置上创建一个窗口,作为工具栏的新容器。

这个就是基本的思路了,下面是浮动工具栏FloatToolstrip 具体的实现代码:

 

 

代码

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Text;

using System.Windows.Forms;

namespace FloatToolStripDemo

{

    public partial class FloatToolstrip : ToolStrip

    {

        private ToolStripPanel tsPanel;

        public FloatToolstrip()

        {

            InitializeComponent();

            this.EndDrag += new EventHandler(MyToolStrip_EndDrag);

            this.SizeChanged += new EventHandler(MyToolStrip_SizeChanged);

        }

        private ToolStripFloatWindow floatForm;

        public ToolStripFloatWindow FloatForm

        {

            get { return floatForm; }

            set

            {

                floatForm = value;

                if (floatForm != null)

                {

                    floatForm.LocationChanged += new EventHandler(floatForm_LocationChanged);

                    floatForm.FormClosing += new FormClosingEventHandler(floatForm_FormClosing);

                }

            }

        }

        void floatForm_FormClosing(object sender, FormClosingEventArgs e)

        {

            e.Cancel = true;

        }

        private void floatForm_LocationChanged(object sender, EventArgs e)

        {

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

            if (this.floatForm == null)

            {

                return;

            }

            else

            {

                if (floatForm.HasCreated)

                {

                    Point currentPt = new Point(floatForm.Location.X, floatForm.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 - 25) && (currentPt.Y < maxPt.Y - 25))

                    {

                        this.floatForm.Controls.Remove(this);

                        this.tsPanel.SuspendLayout();

                        this.tsPanel.Controls.Add(this);

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

                        this.tsPanel.ResumeLayout();

                        this.floatForm.Dispose();

                        this.floatForm = null;

                    }

                }

            }

        }

        public bool isFloating

        {

            get

            {

                return (floatForm != null);

            }

        }

        public ToolStripPanel ToolStripPanel

        {

            get

            {

                return this.tsPanel;

            }

            set

            {

                this.tsPanel = value;

            }

        }

        private void MyToolStrip_EndDrag(object sender, EventArgs e)

        {

            //判断移除时

            if (this.tsPanel == null)

            {

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

                return;

            }

            Point dockPoint = Cursor.Position;

            int openX, openY;

            openX = dockPoint.X;

            openY = dockPoint.Y;

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

            if (clientPt.Y > tsPanel.Height)

            {

                ToolStripFloatWindow tsfw = new ToolStripFloatWindow();

                this.tsPanel.Controls.Remove(this);

                tsfw.Controls.Add(this);

                this.Left = 0;

                this.Top = 0;

                this.FloatForm = tsfw;

                Point newLoc = new Point(openX, openY);

                tsfw.Show();

                tsfw.Location = newLoc;

                tsfw.SetBounds(newLoc.X, newLoc.Y, this.ClientSize.Width, this.ClientSize.Height+25);

            }

        }

        private void MyToolStrip_SizeChanged(object sender, EventArgs e)

        {

            if (this.isFloating)

            {

                this.floatForm.Width = this.ClientSize.Width;

            }

        }

    }

}

 

动态创建的作为浮动工具栏临时容器的窗口,需要加入一些处理技巧,以免发生在创建该窗口的工作尚未结束时,Dispose了这个窗口,这种情况发生在快速拖动工具栏时,触发了EndDrag事件,导致去创建临时窗口作为工具栏新的容器,而这时又将工具栏拖回原停靠容器中,会导致Dispose还没有创建完毕的临时窗口,发生异常!

下面是具体的代码:

代码

 

代码

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;

namespace FloatToolStripDemo

{

    public class ToolStripFloatWindow : Form

    {

        //解决鼠标拖动后,已经正在创建,但是触发Dispose的问题

        private bool hasCreated=false;

        public bool HasCreated

        {

            get

            {

                return hasCreated;

            }

        }

        public ToolStripFloatWindow():base()

        {

            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;

            this.Name = "ToolStripFloatWindow";

            this.ShowIcon = false;

            this.ShowInTaskbar = false;

            this.TopMost = true;

            this.Load += new System.EventHandler(this.ToolStripFloatWindow_Load);

        }

        private void ToolStripFloatWindow_Load(object sender, EventArgs e)

        {

            this.hasCreated = true;

        }

    }

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: