技术改变世界!学习改变自己!

每天进步一点点,遥不可及的事情,在你一点一滴的努力下,也会变成现实。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

image image

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

实现的基本思路如下

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;
        }
    }

 

 

posted on 2010-04-27 17:40  阿捷  阅读(13485)  评论(0编辑  收藏  举报