This documentation is archived and is not being maintained.

Control.DoDragDrop Method

Begins a drag-and-drop operation.

[Visual Basic]
Public Function DoDragDrop( _
   ByVal data As Object, _
   ByVal allowedEffects As DragDropEffects _
) As DragDropEffects
[C#]
public DragDropEffects DoDragDrop(
 object data,
 DragDropEffects allowedEffects
);
[C++]
public: DragDropEffects DoDragDrop(
 Object* data,
 DragDropEffects allowedEffects
);
[JScript]
public function DoDragDrop(
   data : Object,
 allowedEffects : DragDropEffects
) : DragDropEffects;

Parameters

data
The data to drag.
allowedEffects
One of the DragDropEffects values.

Return Value

A value from the DragDropEffects enumeration that represents the final effect that was performed during the drag-and-drop operation.

Remarks

The allowedEffects parameter determines which drag operations can occur. If the drag operation needs to interoperate with applications in another process, data should either be a base managed class (String, Bitmap, or Metafile), or an object that implements ISerializable or IDataObject.

The following describes how and when events related to drag-and-drop operations are raised.

The DoDragDrop method determines the control under the current cursor location. It then checks to see if the control is a valid drop target.

If the control is a valid drop target, the GiveFeedback event is raised with the drag-and-drop effect specified. For a list of drag-and-drop effects, see the DragDropEffects enumeration.

Changes in the mouse cursor position, keyboard state, and mouse button state are tracked.

  • If the user moves out of a window, the DragLeave event is raised.
  • If the mouse enters another control, the DragEnter for that control is raised.
  • If the mouse moves but stays within the same control, the DragOver event is raised.

If there is a change in the keyboard or mouse button state, the QueryContinueDrag event is raised and determines whether to continue the drag, to drop the data, or to cancel the operation based on the value of the Action property of the event's QueryContinueDragEventArgs.

Note   The DragOver and GiveFeedback events are paired so that as the mouse moves across the drop target, the user is given the most up-to-date feedback on the mouse's position.

If the value is DragAction.Drop, the drop effect value is returned to the source, so the source application can perform the appropriate operation on the source data; for example, cut the data if the operation was a move.

If the value is DragAction.Cancel, the DragLeave event is raised.

Example

[Visual Basic, C#, C++] The following example demonstrates a drag-and-drop operation between two ListBox controls. The example calls the DoDragDrop method when the drag action starts. The drag action starts if the mouse has moved more than SystemInformation.DragSize from the mouse location during the MouseDown event. The IndexFromPoint method is used to determine the index of the item to drag during the MouseDown event.

[Visual Basic, C#, C++] The example also demonstrates using custom cursors for the drag-and-drop operation. The example assumes that two cursor files, 3dwarro.cur and 3dwno.cur, exist in the application directory, for the custom drag and no-drop cursors, respectively. The custom cursors will be used if the UseCustomCursorsCheck CheckBox is checked. The custom cursors are set in the GiveFeedback event handler.

[Visual Basic, C#, C++] The keyboard state is evaluated in the DragOver event handler for the right ListBox, to determine what the drag operation will be based upon state of the SHIFT, CTRL, ALT, or CTRL+ALT keys. The location in the ListBox where the drop would occur is also determined during the DragOver event. If the data to drop is not a String, then the DragEventArgs.Effect is set to DragDropEffects.None. Finally, the status of the drop is displayed in the DropLocationLabel Label.

[Visual Basic, C#, C++] The data to drop for the right ListBox is determined in the DragDrop event handler and the String value is added at the appropriate place in the ListBox. If the drag operation moves outside the bounds of the form, then the drag-and-drop operation is canceled in the QueryContinueDrag event handler.

[Visual Basic] 
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public NotInheritable Class Form1
    Inherits System.Windows.Forms.Form

    Friend WithEvents ListDragSource As System.Windows.Forms.ListBox
    Friend WithEvents ListDragTarget As System.Windows.Forms.ListBox
    Friend WithEvents UseCustomCursorsCheck As System.Windows.Forms.CheckBox
    Friend WithEvents DropLocationLabel As System.Windows.Forms.Label

    Private indexOfItemUnderMouseToDrag As Integer
    Private indexOfItemUnderMouseToDrop As Integer

    Private dragBoxFromMouseDown As Rectangle
    Private screenOffset as Point

    Private MyNoDropCursor As Cursor
    Private MyNormalCursor As Cursor

    <System.STAThread()> _
    Public Shared Sub Main()
        System.Windows.Forms.Application.Run(New Form1())
    End Sub 'Main

    Public Sub New()
        MyBase.New()

        Me.ListDragSource = New System.Windows.Forms.ListBox()
        Me.ListDragTarget = New System.Windows.Forms.ListBox()
        Me.UseCustomCursorsCheck = New System.Windows.Forms.CheckBox()
        Me.DropLocationLabel = New System.Windows.Forms.Label()

        Me.SuspendLayout()

        ' ListDragSource
        Me.ListDragSource.Items.AddRange(New Object() {"one", "two", "three", "four", _
                                                            "five", "six", "seven", "eight", _
                                                            "nine", "ten"})
        Me.ListDragSource.Location = New System.Drawing.Point(10, 17)
        Me.ListDragSource.Size = New System.Drawing.Size(120, 225)

        ' ListDragTarget
        Me.ListDragTarget.AllowDrop = True
        Me.ListDragTarget.Location = New System.Drawing.Point(154, 17)
        Me.ListDragTarget.Size = New System.Drawing.Size(120, 225)

        ' UseCustomCursorsCheck
        Me.UseCustomCursorsCheck.Location = New System.Drawing.Point(10, 243)
        Me.UseCustomCursorsCheck.Size = New System.Drawing.Size(137, 24)
        Me.UseCustomCursorsCheck.Text = "Use Custom Cursors"

        ' DropLocationLabel
        Me.DropLocationLabel.Location = New System.Drawing.Point(154, 245)
        Me.DropLocationLabel.Size = New System.Drawing.Size(137, 24)
        Me.DropLocationLabel.Text = "None"

        ' Form1
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 270)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.ListDragSource, _
                                            Me.ListDragTarget, Me.UseCustomCursorsCheck, _
                                            Me.DropLocationLabel})

        Me.Text = "Drag and Drop Example"
        Me.ResumeLayout(False)
    End Sub

    Private Sub ListDragSource_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles ListDragSource.MouseDown

        ' Get the index of the item the mouse is below.
        indexOfItemUnderMouseToDrag = ListDragSource.IndexFromPoint(e.X, e.Y)

        If (indexOfItemUnderMouseToDrag <> ListBox.NoMatches) Then

            ' Remember the point where the mouse down occurred. The DragSize indicates
            ' the size that the mouse can move before a drag event should be started.                
            Dim dragSize As Size = SystemInformation.DragSize

            ' Create a rectangle using the DragSize, with the mouse position being
            ' at the center of the rectangle.
            dragBoxFromMouseDown = New Rectangle(New Point(e.X - (dragSize.Width / 2), _
                                                            e.Y - (dragSize.Height / 2)), dragSize)
        Else
            ' Reset the rectangle if the mouse is not over an item in the ListBox.
            dragBoxFromMouseDown = Rectangle.Empty
        End If

    End Sub

    Private Sub ListDragSource_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles ListDragSource.MouseUp

        ' Reset the drag rectangle when the mouse button is raised.
        dragBoxFromMouseDown = Rectangle.Empty
    End Sub

    Private Sub ListDragSource_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles ListDragSource.MouseMove

        If ((e.Button And MouseButtons.Left) = MouseButtons.Left) Then

            ' If the mouse moves outside the rectangle, start the drag.
            If (Rectangle.op_Inequality(dragBoxFromMouseDown, Rectangle.Empty) And _
                Not dragBoxFromMouseDown.Contains(e.X, e.Y)) Then

                ' Creates custom cursors for the drag-and-drop operation.
                Try
                    MyNormalCursor = New Cursor("3dwarro.cur")
                    MyNoDropCursor = New Cursor("3dwno.cur")

                Catch
                    ' An error occurred while attempting to load the cursors so use
                    ' standard cursors.
                    UseCustomCursorsCheck.Checked = False
                Finally
                    ' The screenOffset is used to account for any desktop bands 
                    ' that may be at the top or left side of the screen when 
                    ' determining when to cancel the drag drop operation.
                    screenOffset = SystemInformation.WorkingArea.Location

                    ' Proceed with the drag and drop, passing in the list item.                    
                    Dim dropEffect As DragDropEffects = ListDragSource.DoDragDrop(ListDragSource.Items(indexOfItemUnderMouseToDrag), _
                                                                                  DragDropEffects.All Or DragDropEffects.Link)

                    ' If the drag operation was a move then remove the item.
                    If (dropEffect = DragDropEffects.Move) Then
                        ListDragSource.Items.RemoveAt(indexOfItemUnderMouseToDrag)

                        ' Select the previous item in the list as long as the list has an item.
                        If (indexOfItemUnderMouseToDrag > 0) Then
                            ListDragSource.SelectedIndex = indexOfItemUnderMouseToDrag - 1

                        ElseIf (ListDragSource.Items.Count > 0) Then
                            ' Selects the first item.
                            ListDragSource.SelectedIndex = 0
                        End If
                    End If

                    ' Dispose the cursors since they are no longer needed.
                    If (Not MyNormalCursor Is Nothing) Then _
                        MyNormalCursor.Dispose()

                    If (Not MyNoDropCursor Is Nothing) Then _
                        MyNoDropCursor.Dispose()
                End Try

            End If
        End If
    End Sub
    Private Sub ListDragSource_GiveFeedback(ByVal sender As Object, ByVal e As GiveFeedbackEventArgs) Handles ListDragSource.GiveFeedback

        ' Use custom cursors if the check box is checked.
        If (UseCustomCursorsCheck.Checked) Then

            ' Set the custom cursor based upon the effect.
            e.UseDefaultCursors = False
            If ((e.Effect And DragDropEffects.Move) = DragDropEffects.Move) Then
                Cursor.Current = MyNormalCursor
            Else
                Cursor.Current = MyNoDropCursor
            End If
        End If

    End Sub

    Private Sub ListDragTarget_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles ListDragTarget.DragOver
        ' Determine whether string data exists in the drop data. If not, then
        ' the drop effect reflects that the drop cannot occur.
        If Not (e.Data.GetDataPresent(GetType(System.String))) Then

            e.Effect = DragDropEffects.None
            DropLocationLabel.Text = "None - no string data."
            Return
        End If

        ' Set the effect based upon the KeyState.
        If ((e.KeyState And (8 + 32)) = (8 + 32) And _
            (e.AllowedEffect And DragDropEffects.Link) = DragDropEffects.Link) Then
            ' KeyState 8 + 32 = CTL + ALT

            ' Link drag and drop effect.
            e.Effect = DragDropEffects.Link

        ElseIf ((e.KeyState And 32) = 32 And _
            (e.AllowedEffect And DragDropEffects.Link) = DragDropEffects.Link) Then

            ' ALT KeyState for link.
            e.Effect = DragDropEffects.Link

        ElseIf ((e.KeyState And 4) = 4 And _
            (e.AllowedEffect And DragDropEffects.Move) = DragDropEffects.Move) Then

            ' SHIFT KeyState for move.
            e.Effect = DragDropEffects.Move

        ElseIf ((e.KeyState And 8) = 8 And _
            (e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy) Then

            ' CTL KeyState for copy.
            e.Effect = DragDropEffects.Copy

        ElseIf ((e.AllowedEffect And DragDropEffects.Move) = DragDropEffects.Move) Then

            ' By default, the drop action should be move, if allowed.
            e.Effect = DragDropEffects.Move

        Else
            e.Effect = DragDropEffects.None
        End If

        ' Gets the index of the item the mouse is below. 

        ' The mouse locations are relative to the screen, so they must be 
        ' converted to client coordinates.

        indexOfItemUnderMouseToDrop = _
            ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(New Point(e.X, e.Y)))

        ' Updates the label text.
        If (indexOfItemUnderMouseToDrop <> ListBox.NoMatches) Then

            DropLocationLabel.Text = "Drops before item #" & (indexOfItemUnderMouseToDrop + 1)
        Else
            DropLocationLabel.Text = "Drops at the end."
        End If

    End Sub

    Private Sub ListDragTarget_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles ListDragTarget.DragDrop
        ' Ensures that the list item index is contained in the data.

        If (e.Data.GetDataPresent(GetType(System.String))) Then

            Dim item As Object = CType(e.Data.GetData(GetType(System.String)), System.Object)

            ' Perform drag and drop, depending upon the effect.
            If (e.Effect = DragDropEffects.Copy Or _
                e.Effect = DragDropEffects.Move) Then

                ' Insert the item.
                If (indexOfItemUnderMouseToDrop <> ListBox.NoMatches) Then
                    ListDragTarget.Items.Insert(indexOfItemUnderMouseToDrop, item)
                Else
                    ListDragTarget.Items.Add(item)

                End If
            End If
            ' Reset the label text.
            DropLocationLabel.Text = "None"
        End If
    End Sub
    Private Sub ListDragSource_QueryContinueDrag(ByVal sender As Object, ByVal e As QueryContinueDragEventArgs) Handles ListDragSource.QueryContinueDrag
        ' Cancel the drag if the mouse moves off the form.
        Dim lb as ListBox = CType(sender, System.Windows.Forms.ListBox)

        If Not (lb is nothing) Then

            Dim f as Form = lb.FindForm()

            ' Cancel the drag if the mouse moves off the form. The screenOffset
            ' takes into account any desktop bands that may be at the top or left
            ' side of the screen.
            If (((Control.MousePosition.X - screenOffset.X) < f.DesktopBounds.Left) Or _
                ((Control.MousePosition.X - screenOffset.X) > f.DesktopBounds.Right) Or _
                ((Control.MousePosition.Y - screenOffset.Y) < f.DesktopBounds.Top) Or _
                ((Control.MousePosition.Y - screenOffset.Y) > f.DesktopBounds.Bottom)) Then

                e.Action = DragAction.Cancel
            End If
        End if
    End Sub
    Private Sub ListDragTarget_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles ListDragTarget.DragEnter

        ' Reset the label text.
        DropLocationLabel.Text = "None"
    End Sub
    Private Sub ListDragTarget_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListDragTarget.DragLeave

        ' Reset the label text.
        DropLocationLabel.Text = "None"
    End Sub
End Class

[C#] 
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Snip_DragNDrop
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.ListBox ListDragSource;
        private System.Windows.Forms.ListBox ListDragTarget;
        private System.Windows.Forms.CheckBox UseCustomCursorsCheck;
        private System.Windows.Forms.Label DropLocationLabel;

        private int indexOfItemUnderMouseToDrag;
        private int indexOfItemUnderMouseToDrop;        
        
        private Rectangle dragBoxFromMouseDown;
        private Point screenOffset;

        private Cursor MyNoDropCursor;
        private Cursor MyNormalCursor;

        /// The main entry point for the application.
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        public Form1()
        {
            this.ListDragSource = new System.Windows.Forms.ListBox();
            this.ListDragTarget = new System.Windows.Forms.ListBox();
            this.UseCustomCursorsCheck = new System.Windows.Forms.CheckBox();
            this.DropLocationLabel = new System.Windows.Forms.Label();

            this.SuspendLayout();

            // ListDragSource
            this.ListDragSource.Items.AddRange(new object[] {"one", "two", "three", "four", 
                                                                "five", "six", "seven", "eight",
                                                                "nine", "ten"});
            this.ListDragSource.Location = new System.Drawing.Point(10, 17);
            this.ListDragSource.Size = new System.Drawing.Size(120, 225);
            this.ListDragSource.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseDown);
            this.ListDragSource.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.ListDragSource_QueryContinueDrag);
            this.ListDragSource.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseUp);
            this.ListDragSource.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ListDragSource_MouseMove);
            this.ListDragSource.GiveFeedback += new System.Windows.Forms.GiveFeedbackEventHandler(this.ListDragSource_GiveFeedback);

            // ListDragTarget
            this.ListDragTarget.AllowDrop = true;
            this.ListDragTarget.Location = new System.Drawing.Point(154, 17);
            this.ListDragTarget.Size = new System.Drawing.Size(120, 225);
            this.ListDragTarget.DragOver += new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragOver);
            this.ListDragTarget.DragDrop += new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragDrop);
            this.ListDragTarget.DragEnter += new System.Windows.Forms.DragEventHandler(this.ListDragTarget_DragEnter);
            this.ListDragTarget.DragLeave += new System.EventHandler(this.ListDragTarget_DragLeave);

            // UseCustomCursorsCheck
            this.UseCustomCursorsCheck.Location = new System.Drawing.Point(10, 243);
            this.UseCustomCursorsCheck.Size = new System.Drawing.Size(137, 24);
            this.UseCustomCursorsCheck.Text = "Use Custom Cursors";

            // DropLocationLabel
            this.DropLocationLabel.Location = new System.Drawing.Point(154, 245);
            this.DropLocationLabel.Size = new System.Drawing.Size(137, 24);
            this.DropLocationLabel.Text = "None";
           
            // Form1
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 270);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {this.ListDragSource,
                                                        this.ListDragTarget, this.UseCustomCursorsCheck,
                                                        this.DropLocationLabel});
            this.Text = "Drag and Drop Example";

            this.ResumeLayout(false);

        }

        private void ListDragSource_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
        {
            // Get the index of the item the mouse is below.
            indexOfItemUnderMouseToDrag = ListDragSource.IndexFromPoint(e.X, e.Y);

            if (indexOfItemUnderMouseToDrag != ListBox.NoMatches) {
                                
                // Remember the point where the mouse down occurred. The DragSize indicates
                // the size that the mouse can move before a drag event should be started.                
                Size dragSize = SystemInformation.DragSize;

                // Create a rectangle using the DragSize, with the mouse position being
                // at the center of the rectangle.
                dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width /2),
                                                               e.Y - (dragSize.Height /2)), dragSize);
            } else
                // Reset the rectangle if the mouse is not over an item in the ListBox.
                dragBoxFromMouseDown = Rectangle.Empty;

        }

        private void ListDragSource_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
            // Reset the drag rectangle when the mouse button is raised.
            dragBoxFromMouseDown = Rectangle.Empty;
        }

        private void ListDragSource_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 
        {
            
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {

                // If the mouse moves outside the rectangle, start the drag.
                if (dragBoxFromMouseDown != Rectangle.Empty && 
                    !dragBoxFromMouseDown.Contains(e.X, e.Y)) {

                    // Create custom cursors for the drag-and-drop operation.
                    try {
                        MyNormalCursor = new Cursor("3dwarro.cur");
                        MyNoDropCursor = new Cursor("3dwno.cur");

                    } catch {
                        // An error occurred while attempting to load the cursors, so use
                        // standard cursors.
                        UseCustomCursorsCheck.Checked = false;
                    }finally {

                        // The screenOffset is used to account for any desktop bands 
                        // that may be at the top or left side of the screen when 
                        // determining when to cancel the drag drop operation.
                        screenOffset = SystemInformation.WorkingArea.Location;

                        // Proceed with the drag and drop, passing in the list item.                    
                        DragDropEffects dropEffect = ListDragSource.DoDragDrop(ListDragSource.Items[indexOfItemUnderMouseToDrag], DragDropEffects.All | DragDropEffects.Link);

                        // If the drag operation was a move then remove the item.
                        if (dropEffect == DragDropEffects.Move) {                        
                            ListDragSource.Items.RemoveAt(indexOfItemUnderMouseToDrag);

                            // Selects the previous item in the list as long as the list has an item.
                            if (indexOfItemUnderMouseToDrag > 0)
                                ListDragSource.SelectedIndex = indexOfItemUnderMouseToDrag -1;

                            else if (ListDragSource.Items.Count > 0)
                                // Selects the first item.
                                ListDragSource.SelectedIndex =0;
                        }

                        // Dispose of the cursors since they are no longer needed.
                        if (MyNormalCursor != null)
                            MyNormalCursor.Dispose();

                        if (MyNoDropCursor != null)
                            MyNoDropCursor.Dispose();
                    }
                }
            }
        }
        private void ListDragSource_GiveFeedback(object sender, System.Windows.Forms.GiveFeedbackEventArgs e) 
        {
            // Use custom cursors if the check box is checked.
            if (UseCustomCursorsCheck.Checked) {

                // Sets the custom cursor based upon the effect.
                e.UseDefaultCursors = false;
                if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move)
                    Cursor.Current = MyNormalCursor;
                else 
                    Cursor.Current = MyNoDropCursor;
            }
        
        }
        private void ListDragTarget_DragOver(object sender, System.Windows.Forms.DragEventArgs e) 
        {

            // Determine whether string data exists in the drop data. If not, then
            // the drop effect reflects that the drop cannot occur.
            if (!e.Data.GetDataPresent(typeof(System.String))) {

                e.Effect = DragDropEffects.None;
                DropLocationLabel.Text = "None - no string data.";
                return;
            }

            // Set the effect based upon the KeyState.
            if ((e.KeyState & (8+32)) == (8+32) && 
                (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
                // KeyState 8 + 32 = CTL + ALT

                // Link drag and drop effect.
                e.Effect = DragDropEffects.Link;

            } else if ((e.KeyState & 32) == 32 && 
                (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {

                // ALT KeyState for link.
                e.Effect = DragDropEffects.Link;

            } else if ((e.KeyState & 4) == 4 && 
                (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {

                // SHIFT KeyState for move.
                e.Effect = DragDropEffects.Move;

            } else if ((e.KeyState & 8) == 8 && 
                (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) {

                // CTL KeyState for copy.
                e.Effect = DragDropEffects.Copy;

            } else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)  {

                // By default, the drop action should be move, if allowed.
                e.Effect = DragDropEffects.Move;

            } else
                e.Effect = DragDropEffects.None;
                
            // Get the index of the item the mouse is below. 

            // The mouse locations are relative to the screen, so they must be 
            // converted to client coordinates.

            indexOfItemUnderMouseToDrop = 
                ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(new Point(e.X, e.Y)));

            // Updates the label text.
            if (indexOfItemUnderMouseToDrop != ListBox.NoMatches){

                DropLocationLabel.Text = "Drops before item #" + (indexOfItemUnderMouseToDrop + 1);
            } else
                DropLocationLabel.Text = "Drops at the end.";

        }
        private void ListDragTarget_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) 
        {
            // Ensure that the list item index is contained in the data.
            if (e.Data.GetDataPresent(typeof(System.String))) {

                Object item = (object)e.Data.GetData(typeof(System.String));

                // Perform drag and drop, depending upon the effect.
                if (e.Effect == DragDropEffects.Copy ||
                    e.Effect == DragDropEffects.Move) {
                
                    // Insert the item.
                    if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
                        ListDragTarget.Items.Insert(indexOfItemUnderMouseToDrop, item);
                    else
                        ListDragTarget.Items.Add(item);
                    
                }
            }
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragSource_QueryContinueDrag(object sender, System.Windows.Forms.QueryContinueDragEventArgs e) {
            // Cancel the drag if the mouse moves off the form.
            ListBox lb = sender as ListBox;

            if (lb != null) {

                Form f = lb.FindForm();

                // Cancel the drag if the mouse moves off the form. The screenOffset
                // takes into account any desktop bands that may be at the top or left
                // side of the screen.
                if (((Control.MousePosition.X - screenOffset.X) < f.DesktopBounds.Left) ||
                    ((Control.MousePosition.X - screenOffset.X) > f.DesktopBounds.Right) ||
                    ((Control.MousePosition.Y - screenOffset.Y) < f.DesktopBounds.Top) ||
                    ((Control.MousePosition.Y - screenOffset.Y) > f.DesktopBounds.Bottom)) {

                    e.Action = DragAction.Cancel;
                }
            }
        }
        private void ListDragTarget_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragTarget_DragLeave(object sender, System.EventArgs e) {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
    }
}

[C++] 

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;

namespace Snip_DragNDrop {
public __gc class Form1 : public System::Windows::Forms::Form {
private:
   System::Windows::Forms::ListBox*  ListDragSource;
   System::Windows::Forms::ListBox*  ListDragTarget;
   System::Windows::Forms::CheckBox*  UseCustomCursorsCheck;
   System::Windows::Forms::Label*  DropLocationLabel;
   Int32  indexOfItemUnderMouseToDrag;
   Int32  indexOfItemUnderMouseToDrop;
   Rectangle  dragBoxFromMouseDown;
   Point  screenOffset;
   System::Windows::Forms::Cursor*  MyNoDropCursor;
   System::Windows::Forms::Cursor*  MyNormalCursor;

public:
   Form1() {
      this->ListDragSource = new System::Windows::Forms::ListBox();
      this->ListDragTarget = new System::Windows::Forms::ListBox();
      this->UseCustomCursorsCheck = new System::Windows::Forms::CheckBox();
      this->DropLocationLabel = new System::Windows::Forms::Label();

      this->SuspendLayout();

      // ListDragSource
      Object* temp0 [] = {
         S"five", S"six", S"seven", S"eight", S"nine", S"ten"
      };
      this->ListDragSource->Items->AddRange(temp0);
      this->ListDragSource->Location = System::Drawing::Point(10, 17);
      this->ListDragSource->Size = System::Drawing::Size(120, 225);
      this->ListDragSource->MouseDown += 
         new System::Windows::Forms::MouseEventHandler(this, &Form1::ListDragSource_MouseDown);
      this->ListDragSource->QueryContinueDrag += 
         new System::Windows::Forms::QueryContinueDragEventHandler(this, &Form1::ListDragSource_QueryContinueDrag);
      this->ListDragSource->MouseUp +=
         new System::Windows::Forms::MouseEventHandler(this, &Form1::ListDragSource_MouseUp);
      this->ListDragSource->MouseMove +=
         new System::Windows::Forms::MouseEventHandler(this, &Form1::ListDragSource_MouseMove);
      this->ListDragSource->GiveFeedback +=
         new System::Windows::Forms::GiveFeedbackEventHandler(this, &Form1::ListDragSource_GiveFeedback);

      // ListDragTarget
      this->ListDragTarget->AllowDrop = true;
      this->ListDragTarget->Location = System::Drawing::Point(154, 17);
      this->ListDragTarget->Size = System::Drawing::Size(120, 225);
      this->ListDragTarget->DragOver +=
         new System::Windows::Forms::DragEventHandler(this, &Form1::ListDragTarget_DragOver);
      this->ListDragTarget->DragDrop +=
         new System::Windows::Forms::DragEventHandler(this, &Form1::ListDragTarget_DragDrop);
      this->ListDragTarget->DragEnter +=
         new System::Windows::Forms::DragEventHandler(this, &Form1::ListDragTarget_DragEnter);
      this->ListDragTarget->DragLeave +=
         new System::EventHandler(this, &Form1::ListDragTarget_DragLeave);

      // UseCustomCursorsCheck
      this->UseCustomCursorsCheck->Location = System::Drawing::Point(10, 243);
      this->UseCustomCursorsCheck->Size = System::Drawing::Size(137, 24);
      this->UseCustomCursorsCheck->Text = S"Use Custom Cursors";

      // DropLocationLabel
      this->DropLocationLabel->Location = System::Drawing::Point(154, 245);
      this->DropLocationLabel->Size = System::Drawing::Size(137, 24);
      this->DropLocationLabel->Text = S"None";

      // Form1
      this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
      this->ClientSize = System::Drawing::Size(292, 270);
      System::Windows::Forms::Control* formControls[] = {this->ListDragSource,
         this->ListDragTarget, this->UseCustomCursorsCheck,
         this->DropLocationLabel};
      this->Controls->AddRange(formControls);
      this->Text = S"Drag and Drop Example";

      this->ResumeLayout(false);

   }

private:
   void ListDragSource_MouseDown(Object* /*sender*/, System::Windows::Forms::MouseEventArgs* e) {
      // Get the index of the item the mouse is below.
      indexOfItemUnderMouseToDrag = this->ListDragSource->IndexFromPoint(e->X, e->Y);

      if (indexOfItemUnderMouseToDrag != ListBox::NoMatches) {

         // Remember the point where the mouse down occurred. The DragSize indicates
         // the size that the mouse can move before a drag event should be started.
         System::Drawing::Size dragSize = SystemInformation::DragSize;

         // Create a rectangle using the DragSize, with the mouse position being
         // at the center of the rectangle.
         dragBoxFromMouseDown = Rectangle(Point(e->X - (dragSize.Width /2),
            e->Y - (dragSize.Height /2)), dragSize);
      } else
         // Reset the rectangle if the mouse is not over an item in the ListBox.
         dragBoxFromMouseDown = Rectangle::Empty;

   }

   void ListDragSource_MouseUp(Object* /*sender*/, System::Windows::Forms::MouseEventArgs* /*e*/) {
      // Reset the drag rectangle when the mouse button is raised.
      dragBoxFromMouseDown = Rectangle::Empty;
   }

private:
   void ListDragSource_MouseMove(Object* /*sender*/, System::Windows::Forms::MouseEventArgs* e) {

      if ((e->Button & MouseButtons::Left) == MouseButtons::Left) {

         // If the mouse moves outside the rectangle, start the drag.
         if (dragBoxFromMouseDown != Rectangle::Empty &&
            !dragBoxFromMouseDown.Contains(e->X, e->Y))
         {

            // Create custom cursors for the drag-and-drop operation.
            try {
               MyNormalCursor = new System::Windows::Forms::Cursor(S"3dwarro.cur");
               MyNoDropCursor = new System::Windows::Forms::Cursor(S"3dwno.cur");

            } catch (Exception*) {
               // An error occurred while attempting to load the cursors, so use
               // standard cursors.
               this->UseCustomCursorsCheck->Checked = false;
            }__finally {

               // The screenOffset is used to account for any desktop bands
               // that may be at the top or left side of the screen when
               // determining when to cancel the drag drop operation.
               screenOffset = SystemInformation::WorkingArea.Location;

               // Proceed with the drag and drop, passing in the list item.
               DragDropEffects dropEffect = this->ListDragSource->DoDragDrop(
                  ListDragSource->Items->Item[indexOfItemUnderMouseToDrag],
                  static_cast<DragDropEffects>(DragDropEffects::All | DragDropEffects::Link));

               // If the drag operation was a move then remove the item.
               if (dropEffect == DragDropEffects::Move) {
                  ListDragSource->Items->RemoveAt(indexOfItemUnderMouseToDrag);

                  // Selects the previous item in the list as long as the list has an item.
                  if (indexOfItemUnderMouseToDrag > 0)
                     ListDragSource->SelectedIndex = indexOfItemUnderMouseToDrag -1;

                  else if (ListDragSource->Items->Count > 0)
                     // Selects the first item.
                     ListDragSource->SelectedIndex =0;
               }

               // Dispose of the cursors since they are no longer needed.
               if (MyNormalCursor != 0)
                  MyNormalCursor->Dispose();

               if (MyNoDropCursor != 0)
                  MyNoDropCursor->Dispose();
            }
         }
      }
   }
private:
   void ListDragSource_GiveFeedback(Object* /*sender*/, 
      System::Windows::Forms::GiveFeedbackEventArgs* e)
   {

      // Use custom cursors if the check box is checked.
      if (UseCustomCursorsCheck->Checked) {

         // Sets the custom cursor based upon the effect.
         e->UseDefaultCursors = false;
         if ((e->Effect & DragDropEffects::Move) == DragDropEffects::Move)
            Cursor::Current = MyNormalCursor;
         else
            Cursor::Current = MyNoDropCursor;
      }

   }
private:
   void ListDragTarget_DragOver(Object* /*sender*/, 
      System::Windows::Forms::DragEventArgs* e)
   {

      // Determine whether string data exists in the drop data. If not, then
      // the drop effect reflects that the drop cannot occur.
      if (!e->Data->GetDataPresent(__typeof(System::String))) {

         e->Effect = DragDropEffects::None;
         DropLocationLabel->Text = S"None - no string data.";
         return;
      }

      // Set the effect based upon the KeyState.
      if ((e->KeyState & (8+32)) == (8+32) &&
         (e->AllowedEffect & DragDropEffects::Link) == DragDropEffects::Link) 
      {
         // KeyState 8 + 32 = CTL + ALT

         // Link drag and drop effect.
         e->Effect = DragDropEffects::Link;

      } else if ((e->KeyState & 32) == 32 &&
         (e->AllowedEffect & DragDropEffects::Link) == DragDropEffects::Link)
      {

         // ALT KeyState for link.
         e->Effect = DragDropEffects::Link;

      } else if ((e->KeyState & 4) == 4 &&
         (e->AllowedEffect & DragDropEffects::Move) == DragDropEffects::Move)
      {
         // SHIFT KeyState for move.
         e->Effect = DragDropEffects::Move;

      } else if ((e->KeyState & 8) == 8 &&
         (e->AllowedEffect & DragDropEffects::Copy) == DragDropEffects::Copy)
      {
         // CTL KeyState for copy.
         e->Effect = DragDropEffects::Copy;

      } else if ((e->AllowedEffect & DragDropEffects::Move) == DragDropEffects::Move)
      {
         // By default, the drop action should be move, if allowed.
         e->Effect = DragDropEffects::Move;

      } else
         e->Effect = DragDropEffects::None;

      // Get the index of the item the mouse is below.

      // The mouse locations are relative to the screen, so they must be
      // converted to client coordinates.

      indexOfItemUnderMouseToDrop =
         ListDragTarget->IndexFromPoint(
         ListDragTarget->PointToClient(Point(e->X, e->Y)));

      // Updates the label text.
      if (indexOfItemUnderMouseToDrop != ListBox::NoMatches) {

         DropLocationLabel->Text = 
            String::Concat(S"Drops before item # ",
            __box( (indexOfItemUnderMouseToDrop + 1)));
      } else
         DropLocationLabel->Text = S"Drops at the end.";

   }
private:
   void ListDragTarget_DragDrop(Object* /*sender*/, 
      System::Windows::Forms::DragEventArgs* e) {
         // Ensure that the list item index is contained in the data.
         if (e->Data->GetDataPresent(__typeof(System::String))) {
            Object* item = dynamic_cast<Object*>(
               e->Data->GetData(__typeof(System::String)));

            // Perform drag and drop, depending upon the effect.
            if (e->Effect == DragDropEffects::Copy ||
               e->Effect == DragDropEffects::Move)
            {

               // Insert the item.
               if (indexOfItemUnderMouseToDrop != ListBox::NoMatches)
                  ListDragTarget->Items->Insert(
                  indexOfItemUnderMouseToDrop, item);
               else
                  ListDragTarget->Items->Add(item);

            }
         }
         // Reset the label text.
         DropLocationLabel->Text = S"None";
      }
private:
   void ListDragSource_QueryContinueDrag(Object* sender, 
      System::Windows::Forms::QueryContinueDragEventArgs* e) {
         // Cancel the drag if the mouse moves off the form.
         ListBox* lb = dynamic_cast<ListBox*>(sender);

         if (lb != 0) {

            Form* f = lb->FindForm();

            // Cancel the drag if the mouse moves off the form. The screenOffset
            // takes into account any desktop bands that may be at the top or left
            // side of the screen.
            if (((Control::MousePosition.X - screenOffset.X) < f->DesktopBounds.Left) ||
               ((Control::MousePosition.X - screenOffset.X) > f->DesktopBounds.Right) ||
               ((Control::MousePosition.Y - screenOffset.Y) < f->DesktopBounds.Top) ||
               ((Control::MousePosition.Y - screenOffset.Y) > f->DesktopBounds.Bottom))
            {

               e->Action = DragAction::Cancel;
            }
         }
      }
private:
   void ListDragTarget_DragEnter(Object* /*sender*/, System::Windows::Forms::DragEventArgs* /*e*/) {
      // Reset the label text.
      DropLocationLabel->Text = S"None";
   }
private:
   void ListDragTarget_DragLeave(Object* /*sender*/, System::EventArgs* /*e*/) {
      // Reset the label text.
      DropLocationLabel->Text = S"None";
   }
};
}

/// The main entry point for the application.
[STAThread]
int main() {
   Application::Run(new Snip_DragNDrop::Form1());
}

[Visual Basic, C#, C++] The following example shows how to use the DragDropEffects enumeration to specify how data should be transferred between the controls involved in a drag-and-drop operation. This example assumes that your form includes a RichTextBox control and a Label control and that the Label control is populated with a list of valid file names. When the user drags a file name onto the RichTextBox control, the control's DragEnter event is raised. Within the event handler, the DragEventArgs object's Effect property is initialized to DragDropEffects to indicate that the data referenced by the file path should be copied to the RichTextBox control.

[Visual Basic] 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   ' Sets the AllowDrop property so that data can be dragged onto the control.
   RichTextBox1.AllowDrop = True

   ' Add code here to populate the ListBox1 with paths to text files.

End Sub

Private Sub RichTextBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles RichTextBox1.DragEnter
   ' If the data is text, copy the data to the RichTextBox control.
   If (e.Data.GetDataPresent("Text")) Then
      e.Effect = DragDropEffects.Copy
   End If
End Sub


Private Overloads Sub RichTextBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles RichTextBox1.DragDrop
   ' Loads the file into the control. 
   RichTextBox1.LoadFile(e.Data.GetData("Text"), System.Windows.Forms.RichTextBoxStreamType.RichText)
End Sub

Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
   Dim Lb As ListBox
   Dim Pt As New Point(e.X, e.Y)
   Dim Index As Integer

   ' Determines which item was selected.
   Lb = sender
   Index = Lb.IndexFromPoint(Pt)

   ' Starts a drag-and-drop operation with that item.
   If Index >= 0 Then
      Lb.DoDragDrop(Lb.Items(Index), DragDropEffects.Link)
   End If
End Sub

[C#] 
private void Form1_Load(object sender, EventArgs e) 
{
   // Sets the AllowDrop property so that data can be dragged onto the control.
   richTextBox1.AllowDrop = true;

   // Add code here to populate the ListBox1 with paths to text files.

}

private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
   // Determines which item was selected.
   ListBox lb =( (ListBox)sender);
   Point pt = new Point(e.X,e.Y);
   int index = lb.IndexFromPoint(pt);

   // Starts a drag-and-drop operation with that item.
   if(index>=0) 
   {
      lb.DoDragDrop(lb.Items[index].ToString(), DragDropEffects.Link);
   }
}

private void richTextBox1_DragEnter(object sender, DragEventArgs e) 
{
   // If the data is text, copy the data to the RichTextBox control.
   if(e.Data.GetDataPresent("Text"))
      e.Effect = DragDropEffects.Copy;
}

private void richTextBox1_DragDrop(object sender, DragEventArgs e) 
{
   // Loads the file into the control. 
   richTextBox1.LoadFile((String)e.Data.GetData("Text"), System.Windows.Forms.RichTextBoxStreamType.RichText);
}


[C++] 
private:
    void Form1_Load(Object* /*sender*/, EventArgs* /*e*/) {
        // Sets the AllowDrop property so that data can be dragged onto the control.
        richTextBox1->AllowDrop = true;

        // Add code here to populate the ListBox1 with paths to text files.
    }

    void listBox1_MouseDown(Object* sender, System::Windows::Forms::MouseEventArgs* e) {
        // Determines which item was selected.
        ListBox* lb =(dynamic_cast<ListBox*>(sender));
        Point pt = Point(e->X, e->Y);
        int index = lb->IndexFromPoint(pt);

        // Starts a drag-and-drop operation with that item.
        if (index>=0) {
            lb->DoDragDrop(lb->Items->Item[index], DragDropEffects::Link);
        }
    }

    void richTextBox1_DragEnter(Object* /*sender*/, DragEventArgs* e) {
        // If the data is text, copy the data to the RichTextBox control.
        if (e->Data->GetDataPresent(S"Text"))
            e->Effect = DragDropEffects::Copy;
    }

    void richTextBox1_DragDrop(Object* /*sender*/, DragEventArgs* e) {
        // Loads the file into the control.
        richTextBox1->LoadFile(dynamic_cast<String*>(e->Data->GetData(S"Text")), 
            System::Windows::Forms::RichTextBoxStreamType::RichText);
    }

[JScript] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family

See Also

Control Class | Control Members | System.Windows.Forms Namespace | AllowDrop | DragDrop

Show: