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 }

 

posted @ 2017-05-06 20:38  此树快长  阅读(1656)  评论(0编辑  收藏  举报