解决WinForm 程序中由于拖拽导致MouseUp事件无法触发的问题
在工作过程中遇到如下问题:
在一个界面上要求控件(LinkLabel)能够拖拽,单击控件要能够跳出窗口。于是按照常规的方法,MouseDown中加入DoDragUp,再加入DragEnter和DragDrop,完事。
发现无法跳出窗口了(跳出窗口写在MouseUp事件中)。
琢磨了很久,也上网找了许多资料,包括MSDN上面的,最后重写控件解决,现总结一下:
一开始想到用双击来代替单击,无奈双击包括单击,就想能不能把他们分开呢?
MSDN上的方法有两个,一个是回滚单击操作,一个是在MouseDown 事件中区分单击和双击
链接:http://msdn.microsoft.com/zh-cn/library/ms171543.aspx,大家可以先参考一下
先说第一种:
关键的在这里:
代码
1 public DoubleClickButton() : base()
2 {
3 // Set the style so a double click event occurs.
4 SetStyle(ControlStyles.StandardClick |
5 ControlStyles.StandardDoubleClick, true);
6 }
2 {
3 // Set the style so a double click event occurs.
4 SetStyle(ControlStyles.StandardClick |
5 ControlStyles.StandardDoubleClick, true);
6 }
测试的时候发现双击事件触发需要单击3次。
第二种方法:
等于是创建一个组件,包括一个Timer用来及时,超过一定时间没有点击第二下的就触发单击事件。
试了一下,发现他是在第一次按下的时候启动TIMER,用来区分单击和双击还是很好的,但是如果是双击和拖拽,或者单击和拖拽的组合那就不行了,另外因为
项目中界面上的LinkLabel数量太多了,怕影响性能。
所以最后只能自己解决啦,思路还是要区分开单击和拖拽,就是在MouseDown中不执行DoDrag,而是置一个标志位,等到拖动控件出了规定的范围后才执行DoDrug,也就是说在MouseMove事件中执行DoDrag,具体代码如下:
代码
1 protected override void OnMouseDown(MouseEventArgs e)
2 {
3 if (e.Button == MouseButtons.Left)
4 {
5 this.IfDoDrag = true;//标志位,需自定义
6 }
7 base.OnMouseDown(e);
8 }
9 protected override void OnMouseMove(MouseEventArgs e)
10 {
11 if (this.IfDoDrag)//还可以加入其它的判断条件,比如拖出多少范围后才触发拖动
12 {
13 this.DoDragDrop(data, DragDropEffects.Move);
14 this.IfDoDrag = false;
15 }
16 base.OnMouseMove(e);
17 }
18 protected override void OnMouseUp(MouseEventArgs e)
19 {
20 this.doDragDrop = false;
24 base.OnMouseUp(e);
25 }
2 {
3 if (e.Button == MouseButtons.Left)
4 {
5 this.IfDoDrag = true;//标志位,需自定义
6 }
7 base.OnMouseDown(e);
8 }
9 protected override void OnMouseMove(MouseEventArgs e)
10 {
11 if (this.IfDoDrag)//还可以加入其它的判断条件,比如拖出多少范围后才触发拖动
12 {
13 this.DoDragDrop(data, DragDropEffects.Move);
14 this.IfDoDrag = false;
15 }
16 base.OnMouseMove(e);
17 }
18 protected override void OnMouseUp(MouseEventArgs e)
19 {
20 this.doDragDrop = false;
24 base.OnMouseUp(e);
25 }
以上是我重写的LinkLabel控件,也可以依样画葫芦重写其它的控件
然后在容器中添加该控件,就像使用普通的LinkLabel一样,添加MouseDown,MouseUp事件,其中MouseDown中需要将需要拖拽的数据data传入控件,而MouseUp中就可以执行先前需要单击执行的操作。
这样,问题就解决了。