I was working on a simple custom control today that displays thumbnails. The thumbnail ordering can be changed by dragging/dropping and you can double click a thumbnail to have a full version of the image pop up in a new dialog. Pretty simple - or is it?
It turns out that the DragDrop functionality is turned on for an object during the MouseDown event. However, when you double click the MouseDown event is also fired and thus the app thinks you are dragging after the first click and the DoubleClick event won’t get fired. What’s a coder to do?
I looked all over for an idea and the best anyone could suggest was combining MouseDown (set a flag) with MouseMove (start DragDrop if flag is set) to start the DragDrop. This doesn’t work too well though if you do a mouseup outside the app (and then drag the mouse back in in the up or down state).
It turns out though that there is a easy and pretty clean solution. The MouseDown event passes along a collection of MouseEventArgs. One of those values is “Clicks” that tells you how many times the mouse was clicked. The event gets called once for a click and again for a double click. So when you double click it calls MouseDown twice. The first time it “enter drag mode” but as soon as you raise the button to click the second time it exits drag mode. The second mousedown has a “Clicks” value of 2 and you can avoid going into drag mode and thus the DoubleClick will be fired.
void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && e.Clicks ==1)
{
PictureBox pb = (PictureBox)sender;
DoDragDrop((ImageData)pb.Tag, DragDropEffects.Copy);
}
}
In the prior example I only want to enter Drag mode if the left button is clicked AND it was only clicked one time. I couldn’t find this information anywhere else so hopefully this post will help someone.
Comments
Anonymous
Thanks, concise and to the point. Saved me some time suckage!
Anonymous
Let’s see .. it’s 2:01 CST August 20, 2012 WAY in the future. Thanks. Looking forward to your next big thing.
Little
It works perfectly. Thanks!
Anonymous
Many thanks!!
Anonymous
THC! Even better than THX!
Crazistor
I had to port my application from Lazarus to C# and you saved me a lot of time with this nice solution. Many thanks!
Crazistor
I had to port my application from Lazarus to C# and you saved me a lot of time with this nice solution. Many thanks!
Eric Enright
Thank you for taking the time to post this snippet. It is exactly the solution I was looking for.
Anonymous
This saved me some time also. Thanks
Anonymous
4.5 years later, folks are still thanking you for posting this. I guess you hit that nail on the head, huh? :)
Duncan
PS: thanking you for posting this!
Anonymous
Thanks, just what I needed. :D
Anonymous
Thanks a lot - this one was really bothering me… :-/
Anonymous
SUPER tip !!!
Thanks, Eddy.
Anonymous
Thanks ! Really :)
Anonymous
easy and works thx
Paul Buisman
Thank you. Solved the problem for me too :-)
Anonymous
thank you !
Anonymous
Again - thanks. One comment. If for any reason it doesn’t work haev a look to ensure that the clickable item is set as AllowDrop. I needed to do this otherwise a double click would treat the item as being dropped onto itself and funny things happened if it wasn’t itself set as AllowDrop.
Bill
To all the thanks - You’re welcome. Glad to help!
Ali Koyuncu
Thank you, dude. You savde my day.
Anonymous
Just what I needed !
Anonymous
Excelente! Gracias!
chuvahin
Thanks. Very helpful
heringer
Thanks!
LambyPie66
Just what I needed and a great explanation - thankyou
sbetberg
Thank You
sbetberg
Thanks
sbetberg
Thank You
steve
Works great. Just had this problem today. ty
Mike
Thanks for the help with this. Unfortunately I still couldn’t get it to work in my TreeView. In fact, it even stopped triple-clicking from invoking the ItemDoubleClick event, which had worked in the past. Maybe I have a strange combination of other things also interfering like AfterSelect events and so on.
For anyone having similar problems to me, though, I did find another workaround where someone has suggested making the DoDragDrop() call from the .ItemDrag() event instead of from the MouseDown() event. Perhaps this just ensures the user is actually trying to drag it beforehand, or something like that.
It seems to work perfectly for me, at least.
Anonymous
thanks :)
Anonymous
Sometimes it’s the little things in life that mean a lot ….
Thank you!
Anonymous
Thanks a lot!!!!
jabbot
Wow, you are a life saver. Ever so simple to think about it. You’ve saved me hours!
Anonymous
Very nice and elegant solution that works :-)
Anonymous
Top stuff. Thanks!
Anonymous
Looked Everywhere for this. Worked like a charm! Thanks!
Dima
1) Thanks for the post!
2) Anonimous - Mouse DoubleClick fires 2 events - one with Clicks==1 and one with Cliks==2. if you put a break point in MouseDown event, then VS2008 will jump on the first click and second will never happen. Try to set a breakpoint with Condition “e.Clicks == 2”.
Bill
I have no idea. I still use VS 2005 and have not had a chance to try out any code in VS 2008.
It seems unlikely that the drag and drop and double click behavior would change so much but it is possible.
Anonymous
This doesn’t work for me. I’m using Visual Studio 2008, and every time I double-click, the MouseDown event always fires with a Clicks == 1.
Could it be that this behavior has changed with VS2008?
Anonymous
thanks!!!!
alexz
Nice solution, thanks!
Richard Potter
Was worried about this - thanks for such an elegant solution
Andreea
Thank you so much !!
Anonymous
Thanks this is great..Keep up the good work!!
james
Thanks, solved a big headache!
Anonymous
Thanks!
Anonymous
Perfect, fast, complete solution to my exact problem. Lots of time saved
Anonymous
Brilliant idea!
Anonymous
Great work. Thanks.
Anonymous
Great !!
Anonymous
Many thanks! I had the same problem, this worked perfectly.
Anonymous
Thanks!!
Mike Lasseter
thanks. this saved my some time googling