May 18, 2007

C# - DragDrop and DoubleClick

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.