zoukankan      html  css  js  c++  java
  • ToolStrip控件左右拖拽移动效果实现

    1.主窗体下部添加一个Panel乘放ToolStrip控件以实现ToolStrip在窗体下部定位。
    2.当ToolStrip控件中子控件超出屏幕时,拖动控件可以实现滑动效果。拖动到控件边缘距窗体边缘1/3宽度时(可设),自动回弹。拖动控件边缘在屏幕内时释放鼠标,控件自动回弹,边缘吸附窗体边缘。
    3.当ToolStrip控件中子控件数目较少可以在屏幕上完全显示时,拖动效果不可见。
    4.增加 添加、删除 按钮,点击时可增删一个ToolStripButton,方便拖动效果可见(ToolStrip控件中子控件超出屏幕)与不可见(ToolStrip控件中子控件可以在屏幕上完全显示时)的演示。
    5.拖动鼠标离开ToolStrip控件再释放,不会触发MouseUp事件,引起控件边缘在屏幕中时释放鼠标自动吸附效果失效。待解决。

     源码:https://files.cnblogs.com/files/tobeforever/DragDemo.rar

    参考文章:WinForm 实现鼠标拖动控件跟随效果(图文) @SkySoot

    http://www.cnblogs.com/SkySoot/archive/2011/12/20/2294733.html

      1 /*==================================================================================================
      2 ** 类 名 称:FrmDragTest
      3 ** 创 建 人:liu
      4 ** 当前版本:V1.0.0
      5 ** CLR 版本:4.0.30319.42000
      6 ** 创建时间:2017/5/6 19:53:44
      7 
      8 ** 修改人        修改时间        修改后版本        修改内容
      9 
     10 
     11 ** 功能描述:ToolStrip控件左右拖拽移动效果实现
     12   
     13  * 主窗体下部添加一个Panel乘放ToolStrip控件以实现ToolStrip在窗体下部定位。
     14  * 当ToolStrip控件中子控件超出屏幕时,拖动控件可以实现滑动效果。拖动到控件边缘距窗体边缘1/3宽度时(可设),
     15    自动回弹。拖动控件边缘在屏幕内时释放鼠标,控件自动回弹,边缘吸附窗体边缘。
     16  * 当ToolStrip控件中子控件数目较少可以在屏幕上完全显示时,拖动效果不可见。
     17  * 增加 添加、删除 按钮,点击时可增删一个ToolStripButton,方便拖动效果可见(ToolStrip控件中子控件超出屏幕)
     18    与不可见(ToolStrip控件中子控件可以在屏幕上完全显示时)的演示。
     19  * 拖动鼠标离开ToolStrip控件再释放,不会触发MouseUp事件,引起控件边缘在屏幕中时释放鼠标自动吸附效果失效。待解决。
     20  
     21 ==================================================================================================
     22  Copyright @2017. liu. All rights reserved.
     23 ==================================================================================================*/
     24 using System;
     25 using System.Drawing;
     26 using System.Windows.Forms;
     27 
     28 namespace DragDemo
     29 {
     30     public partial class FrmDragTest : Form
     31     {
     32         #region 字段
     33 
     34         /// <summary>
     35         /// 被拖动的ToolStrip控件
     36         /// </summary>
     37         private ToolStrip _toolStrip;
     38 
     39         /// <summary>
     40         /// 当前ToolStripButton数目
     41         /// </summary>
     42         private int _itemCount;
     43         
     44         #endregion
     45 
     46         #region 构造
     47 
     48         public FrmDragTest()
     49         {
     50             InitializeComponent();
     51         }
     52         
     53         #endregion
     54 
     55         #region 初始化
     56 
     57         private void FrmTest_Load(object sender, EventArgs e)
     58         {
     59             this.Size = new Size(530, 350);
     60             // 窗体大小调整时,检查边缘是否留白
     61             this.Resize += (sender1, e1) => { CheckBlank(); };
     62             // 添加一个Panel乘放ToolStrip控件以实现ToolStrip在窗体下部定位
     63             var pnlmain = new Panel { Dock = DockStyle.Bottom, Height = 80 };
     64 
     65             _toolStrip = new ToolStrip
     66             {
     67                 // 注意Dock属性必须为None
     68                 Dock = DockStyle.None,
     69                 AutoSize = true,
     70                 //BackgroundImageLayout = ImageLayout.None,
     71                 GripStyle = ToolStripGripStyle.Hidden,
     72                 // 子项除超出屏幕显示时不溢出显示
     73                 LayoutStyle = ToolStripLayoutStyle.Flow,
     74                 Height = 78,
     75                 Location = new Point(0, 1),
     76                 ImageScalingSize = new Size(102, 78)
     77             };
     78 
     79             //默认添加些Button以显示效果
     80             for (int j = 0; j < 10; j++)
     81             {
     82                 AddOneButton();
     83             }
     84 
     85             pnlmain.Controls.Add(_toolStrip);
     86             this.Controls.Add(pnlmain);
     87 
     88             // 添加键
     89             var btnAdd = new Button { Size = new Size(80, 40), Text = @"Add", Location = new Point(150, 100) };
     90             btnAdd.Click += btnAdd_Click;
     91             this.Controls.Add(btnAdd);
     92             // 移除键
     93             var btnRemove = new Button { Size = new Size(80, 40), Text = @"Remove", Location = new Point(300, 100) };
     94             btnRemove.Click += btnRemove_Click;
     95             this.Controls.Add(btnRemove);
     96         }
     97         
     98         #endregion
     99 
    100         #region 自动添加移除
    101 
    102         private void btnAdd_Click(object sender, EventArgs e)
    103         {
    104             AddOneButton();
    105         }
    106 
    107         private void btnRemove_Click(object sender, EventArgs e)
    108         {
    109             RemoveOneButton();
    110         }
    111 
    112         /// <summary>
    113         /// 向_toolStrip添加一个Button
    114         /// </summary>
    115         private void AddOneButton()
    116         {
    117             var tsbtn = new ToolStripButton
    118             {
    119                 AutoSize = false,
    120                 DisplayStyle = ToolStripItemDisplayStyle.Text,
    121                 Text = (++_itemCount).ToString(),
    122                 Size = new Size(100, 78),
    123                 BackColor = Color.YellowGreen,
    124                 Margin = new Padding(0, 0, 2, 0)
    125             };
    126             tsbtn.MouseDown += Controls_MouseDown;
    127             tsbtn.MouseMove += Controls_MouseMove;
    128             tsbtn.MouseUp += Controls_MouseUp;
    129             _toolStrip.Items.Add(tsbtn);
    130         }
    131 
    132         /// <summary>
    133         /// 移除队尾的Button
    134         /// </summary>
    135         private void RemoveOneButton()
    136         {
    137             _toolStrip.Items.RemoveAt(--_itemCount);
    138         }
    139 
    140         #endregion
    141 
    142         #region 拖动效果实现
    143 
    144         /*
    145         * 理解了下面的几个概念,就能完全明白相对坐标的变化.
    146         * Cursor.Position 获取的是相对于用户屏幕的光标坐标
    147         * PointToClient() 方法可将屏幕坐标 Cursor.Position 换算成工作区的坐标
    148         */
    149 
    150         /// <summary>
    151         /// 保存拖动前鼠标X坐标
    152         /// </summary>
    153         private int _curX;
    154         /// <summary>
    155         /// 保存拖动前_ToolStrip控件X坐标
    156         /// </summary>
    157         private int _oldToolStripX;
    158 
    159         /// <summary>
    160         /// 按键按下,记录当前光标X坐标与拖动前_ToolStrip控件X坐标
    161         /// </summary>
    162         /// <param name="sender"></param>
    163         /// <param name="e"></param>
    164         private void Controls_MouseDown(object sender, MouseEventArgs e)
    165         {
    166             if (e.Button == MouseButtons.Left)
    167             {
    168                 // 获取当前光标X坐标
    169                 _curX = Cursor.Position.X;
    170                 // 获取拖动前_ToolStrip控件X坐标
    171                 _oldToolStripX = _toolStrip.Location.X;
    172             }
    173         }
    174 
    175         /// <summary>
    176         /// 鼠标移动,拖动_ToolStrip控件
    177         /// </summary>
    178         /// <param name="sender"></param>
    179         /// <param name="e"></param>
    180         private void Controls_MouseMove(object sender, MouseEventArgs e)
    181         {
    182             if (e.Button == MouseButtons.Left)
    183             {
    184                 // x最小值,对应右侧拖动到边界时x坐标值
    185                 int minX = this.Width - _toolStrip.Width;
    186                 // 图标当前可以全部显示,拖动效果不可见
    187                 if (minX > 0) return;
    188 
    189                 // _ToolStrip控件X轴新坐标
    190                 // 当前鼠标X坐标-拖动前鼠标X坐标=X轴鼠标偏移量,加上拖动前控件X坐标,即为新坐标
    191                 int newToolStripX = Cursor.Position.X - _curX + _oldToolStripX;
    192 
    193                 // 右侧空白超过屏幕宽度1/3,自动回弹
    194                 if (newToolStripX < minX - this.Width / 3)
    195                 {
    196                     // 左拖动过度,修正
    197                     newToolStripX = minX;
    198                 }
    199                 // 左侧空白超过屏幕宽度1/3,自动回弹
    200                 else if (newToolStripX > this.Width / 3)
    201                 {
    202                     // 右拖动过多,修正
    203                     newToolStripX = 0;
    204                 }
    205 
    206                 _toolStrip.Location = new Point(newToolStripX, 0);
    207             }
    208         }
    209 
    210         /// <summary>
    211         /// 鼠标松开,检查两侧是否留白
    212         /// </summary>
    213         /// <param name="sender"></param>
    214         /// <param name="e"></param>
    215         private void Controls_MouseUp(object sender, MouseEventArgs e)
    216         {
    217             if (e.Button == MouseButtons.Left)
    218             {
    219                 CheckBlank();
    220             }
    221         }
    222 
    223         /// <summary>
    224         /// 检查两侧是否留白
    225         /// </summary>
    226         private void CheckBlank()
    227         {
    228 
    229             // x最小值,对应右侧拖动到边界时x坐标值
    230             int minX = this.Width - _toolStrip.Width;
    231             // 图标全部显示,拖动效果不可见
    232             if (minX > 0) return;
    233 
    234             // 左边界限制,左侧不留空
    235             if (_toolStrip.Location.X > 0)
    236             {
    237                 _toolStrip.Location = new Point(0, 0);
    238             }
    239             // 右边界限制,右侧不留空
    240             else if (_toolStrip.Location.X < minX)
    241             {
    242                 _toolStrip.Location = new Point(minX, 0);
    243             }
    244 
    245         }
    246 
    247 
    248 
    249         #endregion
    250     }
    251 }
  • 相关阅读:
    Spark学习笔记2(spark所需环境配置
    Spark学习笔记1(初始spark
    zookeeper基本讲解及基本命令和配置 (转)
    计算机网络面试常考(转载)
    C++面试笔试题汇总
    复杂指针解析
    如何限制一个类对象只在栈(堆)上分配空间?
    虚函数实现机制
    C++内存分配方式详解
    C++中指针和引用的区别(转载)
  • 原文地址:https://www.cnblogs.com/tobeforever/p/6818072.html
Copyright © 2011-2022 走看看