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

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

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 ;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值