The DoDragDrop method on a control is synchronous. This means that when you call DoDragDrop to start a drag operation, the program will not return and execute the rest of your handler code until the user 1) drops the data she is dragging, or 2) cancels the drag operation. This is one of those little facts that you need to file away in your brain, as it could have a profound effect on your drag & drop logic.

Simple Example

In the sample code below, when the user clicks the left mouse button on a Panel control, its MouseDown handler saves the mouse pointer location in the m_ClickLocation member.

In the MouseMove handler, if the left mouse button is still down, the current mouse pointer location is compared to the saved location. If the pointer has moved more than the DragSize property in the SystemInformation class, the DoDragDrop method is called to start the drag operation.

Note that DragSize represents the size of the “rectangle centered on the point the mouse button was pressed, within which a drag operation will not begin.” So to calculate how far the mouse pointer must move horizontally to start a drag operation, for example, you must divide DragSize.Width by 2.

        private Point m_ClickLocation;
        private void panel1_MouseDown( object sender, MouseEventArgs e )
        {
            Console.WriteLine( "MouseDown" );
            if (e.Button == MouseButtons.Left)
                this.m_ClickLocation = e.Location;
        }
        private void panel1_MouseMove( object sender, MouseEventArgs e )
        {
            Console.WriteLine( "MouseMoveBegin" );
            if (e.Button == MouseButtons.Left)
            {
                Size dragSize = SystemInformation.DragSize;
                if (Math.Abs( e.X - this.m_ClickLocation.X ) > dragSize.Width / 2 ||
                    Math.Abs( e.Y - this.m_ClickLocation.Y ) > dragSize.Height / 2)
                {
                    this.panel1.DoDragDrop( "test", DragDropEffects.Copy );
                }
            }
            Console.WriteLine( "MouseMoveEnd" );
        }
        private void form1_DragDrop( object sender, DragEventArgs e )
        {
            Console.WriteLine( "DragDrop" );
        }
        private void form1_DragOver( object sender, DragEventArgs e )
        {
            Console.WriteLine( "DragOver" );
        }

Program Output

Since DoDragDrop is synchronous, program execution will not return to the MouseMove handler until after the user drops the data or cancels the drag operation. Hence, the output for this sample program might look like this:

MouseDown
MouseMoveBegin
MouseMoveEnd
MouseMoveBegin
DragOver
DragOver
DragDrop
MouseMoveEnd

Notice how MouseMoveEnd didn’t occur until after the drag & drop operation (and hence the DoDragDrop method) had completed.

Share and Enjoy:
  • Digg
  • Twitter
  • Facebook
  • Reddit
  • StumbleUpon
  • LinkedIn
  • Google Bookmarks
  • Slashdot