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
所谓的浮动工具栏,效果图如下:
也就是说,可以将工具栏拖出其原先的停靠位置,而且可以将拖出来的工具栏再拖放回去。
实现的基本思路如下
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
- C# ToolStrip浮动工具栏及上/下/左/右 停靠
- C# ToolStrip浮动及上/下/左/右 停靠
- C# ToolStrip浮动及上/下/左/右 停靠
- C# 工具栏ToolStrip
- 左浮动和右浮动
- 工具栏ToolStrip
- 在mfc的sdi/mdi程序任意视图view内创建可停靠及浮动的工具栏方法
- symbian 键值对应表,上、下、左、右、左软键、右软键、中间键
- JS无缝滚动(上、下、左、右)
- table的左/右/上/下边框处理
- 如何隐藏table的左/右/上/下边框
- js图片(上、下、左、右)无缝滚动代码
- Android手势(上,下,左和右的判断)
- Android手势(上,下,左和右的判断)
- 如何隐藏table的左/右/上/下边框
- Android手势(上,下,左和右的判断)
- popwindow在View的上,下,左,右 显示
- Appium+java代码实现上/下/左/右滑动
- 公式编辑器中有几种不同的省略号
- 《汇编语言》学习(十一)标志寄存器
- 本地 Mac 搭建 IPv6 测试环境
- PHP中fopen,file_get_contents,curl函数的区别和性能
- Intellij IDEA的Facets和Artifacts
- C# ToolStrip浮动工具栏及上/下/左/右 停靠
- build.gradle配置记录一
- pause命令
- Android testview editText 输入价格(0.00的格式)和件数(没有小数)的监听器
- linux内核中的list.h文件中线性链表的分析(二)
- seaser2
- 命令行大全
- angularjs 在指令中通过dom修改input 的Value值同时更新model
- Linux应用层中的setitimer的使用说明