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

来源:互联网 发布:贵州广电网络怎么缴费 编辑:程序博客网 时间:2024/05/16 06:17

此文转自http://blog.csdn.net/luols/article/details/7258829

关于浮动工具条的制作,阿捷写了一篇很不错的文章,见:http://www.cnblogs.com/ajiefj/archive/2010/04/27/1722256.html

所谓的浮动工具栏,效果图如下:

imageimage

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

实现的基本思路如下

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

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

ShowIcon = false;

ShowInTaskbar = false;

TopMost = true;

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

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

代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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还没有创建完毕的临时窗口,发生异常!

下面是具体的代码:

代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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;        }    }}


阿捷这个工具条浮动后只能在顶部停靠,基于此,我在这边增加在左/右/底部停靠,停靠条件是浮动窗体紧贴或越过主窗体边缘。

其实阿捷给出的代码已经相当详细了:) 我这里主要给出重写的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


0 0
原创粉丝点击