解决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         }

 

测试的时候发现双击事件触发需要单击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         }

 

以上是我重写的LinkLabel控件,也可以依样画葫芦重写其它的控件

然后在容器中添加该控件,就像使用普通的LinkLabel一样,添加MouseDown,MouseUp事件,其中MouseDown中需要将需要拖拽的数据data传入控件,而MouseUp中就可以执行先前需要单击执行的操作。

 

这样,问题就解决了。

posted @ 2010-03-13 09:26  赤红十三  阅读(3220)  评论(0编辑  收藏  举报