다음을 통해 공유


Control.DoDragDrop 메서드

정의

오버로드

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean)

끌기 작업을 시작합니다.

DoDragDrop(Object, DragDropEffects)

끌어서 놓기 작업을 시작합니다.

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean)

끌기 작업을 시작합니다.

public:
 System::Windows::Forms::DragDropEffects DoDragDrop(System::Object ^ data, System::Windows::Forms::DragDropEffects allowedEffects, System::Drawing::Bitmap ^ dragImage, System::Drawing::Point cursorOffset, bool useDefaultDragImage);
public System.Windows.Forms.DragDropEffects DoDragDrop (object data, System.Windows.Forms.DragDropEffects allowedEffects, System.Drawing.Bitmap? dragImage, System.Drawing.Point cursorOffset, bool useDefaultDragImage);
member this.DoDragDrop : obj * System.Windows.Forms.DragDropEffects * System.Drawing.Bitmap * System.Drawing.Point * bool -> System.Windows.Forms.DragDropEffects
Public Function DoDragDrop (data As Object, allowedEffects As DragDropEffects, dragImage As Bitmap, cursorOffset As Point, useDefaultDragImage As Boolean) As DragDropEffects

매개 변수

data
Object
allowedEffects
DragDropEffects
dragImage
Bitmap
cursorOffset
Point
useDefaultDragImage
Boolean

반환

끌어서 놓기 작업 중에 수행된 최종 효과를 나타내는 DragDropEffects 열거형의 값입니다.

설명

allowedEffects 매개 변수는 발생할 수 있는 끌기 작업을 결정합니다. 끌기 작업이 다른 프로세스에서 애플리케이션과 상호 작용해야 하는 경우 data 기본 관리 클래스(String, Bitmap또는 Metafile)이거나 ISerializable구현하는 일부 Object 있어야 합니다. data IDataObject구현하는 모든 Object 될 수도 있습니다. dragImage 끌기 작업 중에 표시되는 비트맵이며 cursorOffset 왼쪽 위 모서리에서 오프셋인 dragImage내에서 커서의 위치를 지정합니다. 크기가 96x96인 계층화된 창 끌기 이미지를 사용하도록 useDefaultDragImagetrue 지정합니다. 그렇지 않으면 false. 이미지 너비 또는 높이가 300픽셀을 초과하는 경우 dragImage 바깥 쪽 가장자리가 혼합됩니다.

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean) 항상 알파 값을 계산하는 RGB 곱하기 단계를 수행하므로 미리 계산된 알파 혼합 없이 항상 Bitmap 전달해야 합니다. 미리 곱한 알파 혼합을 사용하여 Bitmap 전달하면 오류가 발생하지 않지만 이 메서드는 다시 곱하여 결과 알파 값을 두 배로 곱합니다.

적용 대상

DoDragDrop(Object, DragDropEffects)

끌어서 놓기 작업을 시작합니다.

public:
 System::Windows::Forms::DragDropEffects DoDragDrop(System::Object ^ data, System::Windows::Forms::DragDropEffects allowedEffects);
public System.Windows.Forms.DragDropEffects DoDragDrop (object data, System.Windows.Forms.DragDropEffects allowedEffects);
member this.DoDragDrop : obj * System.Windows.Forms.DragDropEffects -> System.Windows.Forms.DragDropEffects
Public Function DoDragDrop (data As Object, allowedEffects As DragDropEffects) As DragDropEffects

매개 변수

data
Object

끌 데이터입니다.

allowedEffects
DragDropEffects

DragDropEffects 값 중 하나입니다.

반환

끌어서 놓기 작업 중에 수행된 최종 효과를 나타내는 DragDropEffects 열거형의 값입니다.

예제

다음 코드 예제에서는 두 ListBox 컨트롤 간의 끌어서 놓기 작업을 보여 줍니다. 이 예제에서는 끌기 작업이 시작될 때 DoDragDrop 메서드를 호출합니다. 마우스가 MouseDown 이벤트 중에 마우스 위치에서 SystemInformation.DragSize 이상 이동한 경우 끌기 작업이 시작됩니다. IndexFromPoint 메서드는 MouseDown 이벤트 중에 끌 항목의 인덱스 확인에 사용됩니다.

또한 이 예제에서는 끌어서 놓기 작업에 사용자 지정 커서를 사용하는 방법을 보여 줍니다. 이 예제에서는 3dwarro.cur3dwno.cur두 개의 커서 파일이 각각 사용자 지정 끌어서 놓기 커서에 대해 애플리케이션 디렉터리에 있어야 합니다. UseCustomCursorsCheck CheckBox 선택하면 사용자 지정 커서가 사용됩니다. 사용자 지정 커서는 GiveFeedback 이벤트 처리기에 설정됩니다.

키보드 상태는 오른쪽 ListBox대한 DragOver 이벤트 처리기에서 평가되어 Shift, Ctrl, Alt 또는 Ctrl+Alt 키의 상태를 기준으로 끌기 작업을 결정합니다. 드롭이 발생하는 ListBox 위치도 DragOver 이벤트 중에 결정됩니다. 삭제할 데이터가 String아닌 경우 DragEventArgs.EffectDragDropEffectsNone 설정됩니다. 마지막으로 드롭 상태가 DropLocationLabelLabel표시됩니다.

오른쪽 ListBox 대해 삭제할 데이터는 DragDrop 이벤트 처리기에서 결정되며 String 값은 ListBox적절한 위치에 추가됩니다. 끌기 작업이 폼의 범위 밖으로 이동하면 QueryContinueDrag 이벤트 처리기에서 끌어서 놓기 작업이 취소됩니다.

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

namespace Snip_DragNDrop
{
   public ref 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 = gcnew System::Windows::Forms::ListBox;
         this->ListDragTarget = gcnew System::Windows::Forms::ListBox;
         this->UseCustomCursorsCheck = gcnew System::Windows::Forms::CheckBox;
         this->DropLocationLabel = gcnew System::Windows::Forms::Label;
         this->SuspendLayout();
         
         // ListDragSource
         array<Object^>^temp0 = {"five","six","seven","eight","nine","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 += gcnew System::Windows::Forms::MouseEventHandler( this, &Form1::ListDragSource_MouseDown );
         this->ListDragSource->QueryContinueDrag += gcnew System::Windows::Forms::QueryContinueDragEventHandler( this, &Form1::ListDragSource_QueryContinueDrag );
         this->ListDragSource->MouseUp += gcnew System::Windows::Forms::MouseEventHandler( this, &Form1::ListDragSource_MouseUp );
         this->ListDragSource->MouseMove += gcnew System::Windows::Forms::MouseEventHandler( this, &Form1::ListDragSource_MouseMove );
         this->ListDragSource->GiveFeedback += gcnew 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 += gcnew System::Windows::Forms::DragEventHandler( this, &Form1::ListDragTarget_DragOver );
         this->ListDragTarget->DragDrop += gcnew System::Windows::Forms::DragEventHandler( this, &Form1::ListDragTarget_DragDrop );
         this->ListDragTarget->DragEnter += gcnew System::Windows::Forms::DragEventHandler( this, &Form1::ListDragTarget_DragEnter );
         this->ListDragTarget->DragLeave += gcnew 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 = "Use Custom Cursors";
         
         // DropLocationLabel
         this->DropLocationLabel->Location = System::Drawing::Point( 154, 245 );
         this->DropLocationLabel->Size = System::Drawing::Size( 137, 24 );
         this->DropLocationLabel->Text = "None";
         
         // Form1
         this->ClientSize = System::Drawing::Size( 292, 270 );
         array<System::Windows::Forms::Control^>^formControls = {this->ListDragSource,this->ListDragTarget,this->UseCustomCursorsCheck,this->DropLocationLabel};
         this->Controls->AddRange( formControls );
         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 = 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
                  dragBoxFromMouseDown = Rectangle::Empty;

         
         // Reset the rectangle if the mouse is not over an item in the ListBox.
      }

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


      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 = gcnew System::Windows::Forms::Cursor( "3dwarro.cur" );
                  MyNoDropCursor = gcnew System::Windows::Forms::Cursor( "3dwno.cur" );
               }
               catch ( Exception^ ) 
               {
                  // An error occurred while attempting to load the cursors, so use
                  // the 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[ 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 != nullptr )
                                    delete MyNormalCursor;
                  if ( MyNoDropCursor != nullptr )
                                    delete MyNoDropCursor;
               }
            }
         }
      }

      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;
         }
      }

      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( System::String::typeid ) )
         {
            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 = CTRL + 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) )
         {
            // CTRL 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( "Drops before item # ", (indexOfItemUnderMouseToDrop + 1) );
         }
         else
                  DropLocationLabel->Text = "Drops at the end.";
      }

      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( System::String::typeid ) )
         {
            Object^ item = dynamic_cast<Object^>(e->Data->GetData( System::String::typeid ));
            
            // 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";
      }

      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 != nullptr )
         {
            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;
            }
         }
      }

      void ListDragTarget_DragEnter( Object^ /*sender*/, System::Windows::Forms::DragEventArgs^ /*e*/ )
      {
         // Reset the label text.
         DropLocationLabel->Text = "None";
      }

      void ListDragTarget_DragLeave( Object^ /*sender*/, System::EventArgs^ /*e*/ )
      {
        // Reset the label text.
         DropLocationLabel->Text = "None";
      }
   };
}

/// The main entry point for the application.

[STAThread]
int main()
{
   Application::Run( gcnew Snip_DragNDrop::Form1 );
}
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Snip_DragNDrop
{
    public class Form1 : Form
    {
        private ListBox ListDragSource;
        private ListBox ListDragTarget;
        private CheckBox UseCustomCursorsCheck;
        private 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 ListBox();
            this.ListDragTarget = new ListBox();
            this.UseCustomCursorsCheck = new CheckBox();
            this.DropLocationLabel = new Label();

            this.SuspendLayout();

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

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

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

            // DropLocationLabel
            this.DropLocationLabel.Location = new Point(154, 245);
            this.DropLocationLabel.Size = new Size(137, 24);
            this.DropLocationLabel.Text = "None";

            // Form1
            this.ClientSize = new Size(292, 270);
            this.Controls.AddRange(new Control[] {
                this.ListDragSource,
                this.ListDragTarget,
                this.UseCustomCursorsCheck,
                this.DropLocationLabel});
            this.Text = "drag-and-drop Example";

            this.ResumeLayout(false);
        }

        private void ListDragSource_MouseDown(object sender, 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, MouseEventArgs e)
        {
            // Reset the drag rectangle when the mouse button is raised.
            dragBoxFromMouseDown = Rectangle.Empty;
        }

        private void ListDragSource_MouseMove(object sender, 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, 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, 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 = CTRL + 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)
            {
                // CTRL 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, DragEventArgs e)
        {
            // Ensure that the list item index is contained in the data.
            if (e.Data.GetDataPresent(typeof(System.String)))
            {
                Object item = 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, 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, DragEventArgs e)
        {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragTarget_DragLeave(object sender, EventArgs e)
        {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
    }
}
Imports System.Drawing
Imports System.Windows.Forms

Public NotInheritable Class Form1
    Inherits Form

    Friend WithEvents ListDragSource As ListBox
    Friend WithEvents ListDragTarget As ListBox
    Friend WithEvents UseCustomCursorsCheck As CheckBox
    Friend WithEvents DropLocationLabel As 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

    <STAThread()>
    Public Shared Sub Main()
        Application.Run(New Form1())
    End Sub

    Public Sub New()
        MyBase.New()

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

        Me.SuspendLayout()

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

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

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

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

        ' Form1
        Me.ClientSize = New Size(292, 270)
        Me.Controls.AddRange(New 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 = CTRL + 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

            ' CTRL 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, ListBox)

        If (lb IsNot 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 EventArgs) Handles ListDragTarget.DragLeave
        ' Reset the label text.
        DropLocationLabel.Text = "None"
    End Sub
End Class

다음 코드 예제에서는 DragDropEffects 열거형을 사용하여 끌어서 놓기 작업과 관련된 컨트롤 간에 데이터를 전송하는 방법을 지정하는 방법을 보여 줍니다. 이 예제에서는 양식에 RichTextBox 컨트롤과 ListBox 컨트롤이 포함되어 있고 ListBox 컨트롤이 유효한 파일 이름 목록으로 채워져 있어야 합니다. 사용자가 파일 이름을 RichTextBox 컨트롤로 끌면 컨트롤의 DragEnter 이벤트가 발생합니다. 이벤트 처리기 내에서 파일 경로에서 참조하는 데이터를 RichTextBox 컨트롤에 복사해야 함을 나타내기 위해 DragEventArgsEffect 속성이 DragDropEffects 초기화됩니다.

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[ 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( "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( "Text" )), System::Windows::Forms::RichTextBoxStreamType::RichText );
   }
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);
}
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

설명

allowedEffects 매개 변수는 발생할 수 있는 끌기 작업을 결정합니다. 끌기 작업이 다른 프로세스에서 애플리케이션과 상호 운용되어야 하는 경우 데이터는 기본 관리 클래스(String, Bitmap또는 Metafile)이거나 ISerializable 또는 IDataObject구현하는 개체여야 합니다.

다음은 끌어서 놓기 작업과 관련된 이벤트가 발생하는 방법과 시기에 대해 설명합니다.

DoDragDrop 메서드는 현재 커서 위치 아래의 컨트롤을 결정합니다. 그런 다음 컨트롤이 유효한 놓기 대상인지 확인합니다.

컨트롤이 유효한 놓기 대상인 경우 끌어서 놓기 효과가 지정된 GiveFeedback 이벤트가 발생합니다. 끌어서 놓기 효과 목록은 DragDropEffects 열거형을 참조하세요.

마우스 커서 위치, 키보드 상태 및 마우스 단추 상태의 변경 내용이 추적됩니다.

  • 사용자가 창 밖으로 이동하면 DragLeave 이벤트가 발생합니다.

  • 마우스가 다른 컨트롤에 들어가면 해당 컨트롤의 DragEnter 발생합니다.

  • 마우스가 이동하지만 동일한 컨트롤 내에 있으면 DragOver 이벤트가 발생합니다.

키보드 또는 마우스 단추 상태가 변경되면 QueryContinueDrag 이벤트가 발생하고 끌기를 계속할지, 데이터를 삭제할지, 아니면 이벤트 QueryContinueDragEventArgsAction 속성 값에 따라 작업을 취소할지 결정합니다.

  • DragAction 값이 Continue경우 작업을 계속하기 위해 DragOver 이벤트가 발생하고 적절한 시각적 피드백을 설정할 수 있도록 새 효과와 함께 GiveFeedback 이벤트가 발생합니다. 유효한 드롭 효과 목록은 DragDropEffects 열거형을 참조하세요.

    메모

    DragOverGiveFeedback 이벤트는 마우스가 놓기 대상을 가로질러 이동할 때 마우스 위치에 대한 가장 up-to날짜 피드백을 받도록 쌍을 이립니다.

  • DragAction 값이 Drop경우 원본 애플리케이션이 원본 데이터에 대해 적절한 작업을 수행할 수 있도록 놓기 효과 값이 원본에 반환됩니다. 예를 들어 작업이 이동인 경우 데이터를 잘라냅니다.

  • DragAction 값이 Cancel경우 DragLeave 이벤트가 발생합니다.

메모

DoDragDrop 메서드는 모든 예외를 catch하고 다음 보안 또는 중요한 예외만 다시 throw합니다.

  • SecurityException

  • NullReferenceException

  • StackOverflowException

  • OutOfMemoryException

  • ThreadAbortException

  • ExecutionEngineException

  • IndexOutOfRangeException

  • AccessViolationException

추가 정보

적용 대상