본문 바로가기
📁 [4] 개발자 정보 & 코드 노트/C#

C# Windows Forms 강의 16편: Drag & Drop (드래그 앤 드롭) 기능 구현

by wawManager 2025. 2. 19.

1. 강의 개요

이번 강의에서는 Windows Forms에서 Drag & Drop(드래그 앤 드롭) 기능을 구현하는 방법을 학습합니다.
Drag & Drop은 사용자가 데이터를 끌어다 놓는 방식으로 애플리케이션과 상호작용할 수 있도록 합니다.


2. 학습 목표

  1. Windows Forms 컨트롤에 Drag & Drop 기능을 활성화.
  2. 파일, 텍스트 등 다양한 데이터를 드래그 앤 드롭으로 처리.
  3. 이벤트(DragEnter, DragDrop)를 통해 드래그 상태 및 드롭 동작 구현.

3. Drag & Drop이란?

Drag & Drop 동작 과정

  1. Drag 시작: 데이터를 드래그하려면 마우스로 클릭하고 끌기 시작.
  2. Drag 상태: 다른 컨트롤 위로 드래그가 진행되며, 드롭 가능 여부를 결정.
  3. Drop 완료: 드롭 위치에서 데이터를 처리.

Drag & Drop 관련 주요 이벤트

이벤트 설명 예제

DragEnter 드래그된 데이터가 컨트롤 영역에 들어올 때 발생 textBox1.DragEnter += TextBox1_DragEnter;
DragDrop 드롭이 완료될 때 발생 textBox1.DragDrop += TextBox1_DragDrop;
DragOver 드래그된 데이터가 컨트롤 위에 있는 동안 발생 listBox1.DragOver += ListBox1_DragOver;
MouseDown Drag 시작을 위해 사용자가 클릭했을 때 발생 label1.MouseDown += Label1_MouseDown;

4. 실습: Drag & Drop으로 파일 및 텍스트 처리

요구사항

  1. Label 컨트롤을 드래그하여 ListBox로 드롭.
  2. 외부 파일을 ListBox에 드롭하여 파일 이름 표시.
  3. TextBox에 드래그된 텍스트를 표시.

폼 구성

컨트롤 타입 이름 텍스트 위치 크기

Label lblDraggable "드래그하세요" (20, 20) (100 x 30)
ListBox listBox1 (없음) (20, 60) (300 x 150)
TextBox textBox1 (없음) (20, 230) (300 x 30)

코드 작성

Form1.cs

using System;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeDragAndDrop();
        }

        private void InitializeDragAndDrop()
        {
            // Label을 드래그 가능하도록 설정
            lblDraggable.MouseDown += LblDraggable_MouseDown;

            // ListBox에 Drag & Drop 이벤트 연결
            listBox1.AllowDrop = true;
            listBox1.DragEnter += ListBox1_DragEnter;
            listBox1.DragDrop += ListBox1_DragDrop;

            // TextBox에 Drag & Drop 이벤트 연결
            textBox1.AllowDrop = true;
            textBox1.DragEnter += TextBox1_DragEnter;
            textBox1.DragDrop += TextBox1_DragDrop;
        }

        // Label의 MouseDown 이벤트: 드래그 시작
        private void LblDraggable_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                lblDraggable.DoDragDrop(lblDraggable.Text, DragDropEffects.Copy);
            }
        }

        // ListBox의 DragEnter 이벤트: 드래그된 데이터가 들어올 때
        private void ListBox1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                e.Effect = DragDropEffects.Copy; // 드롭 가능
            }
            else
            {
                e.Effect = DragDropEffects.None; // 드롭 불가능
            }
        }

        // ListBox의 DragDrop 이벤트: 드롭이 완료되었을 때
        private void ListBox1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                foreach (string file in files)
                {
                    listBox1.Items.Add(Path.GetFileName(file)); // 파일 이름 추가
                }
            }
            else if (e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                string text = (string)e.Data.GetData(DataFormats.StringFormat);
                listBox1.Items.Add(text); // 텍스트 추가
            }
        }

        // TextBox의 DragEnter 이벤트: 드래그된 데이터가 들어올 때
        private void TextBox1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                e.Effect = DragDropEffects.Copy; // 드롭 가능
            }
            else
            {
                e.Effect = DragDropEffects.None; // 드롭 불가능
            }
        }

        // TextBox의 DragDrop 이벤트: 드롭이 완료되었을 때
        private void TextBox1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                string text = (string)e.Data.GetData(DataFormats.Text);
                textBox1.Text = text; // 텍스트 박스에 드롭된 텍스트 표시
            }
        }
    }
}

디자이너 코드: Form1.Designer.cs

namespace WindowsFormsApp1
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;
        private Label lblDraggable;
        private ListBox listBox1;
        private TextBox textBox1;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.lblDraggable = new Label();
            this.listBox1 = new ListBox();
            this.textBox1 = new TextBox();
            this.SuspendLayout();

            // lblDraggable
            this.lblDraggable.AutoSize = true;
            this.lblDraggable.Location = new System.Drawing.Point(20, 20);
            this.lblDraggable.Name = "lblDraggable";
            this.lblDraggable.Size = new System.Drawing.Size(100, 20);
            this.lblDraggable.TabIndex = 0;
            this.lblDraggable.Text = "드래그하세요";

            // listBox1
            this.listBox1.FormattingEnabled = true;
            this.listBox1.ItemHeight = 20;
            this.listBox1.Location = new System.Drawing.Point(20, 60);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(300, 150);
            this.listBox1.TabIndex = 1;

            // textBox1
            this.textBox1.Location = new System.Drawing.Point(20, 230);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(300, 27);
            this.textBox1.TabIndex = 2;

            // Form1
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(350, 300);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.listBox1);
            this.Controls.Add(this.lblDraggable);
            this.Name = "Form1";
            this.Text = "Drag & Drop 예제";
            this.ResumeLayout(false);
            this.PerformLayout();
        }
    }
}

6. 실행 결과

  1. Label 드래그
    • "드래그하세요" Label을 드래그하여 ListBox에 드롭하면 텍스트가 추가됩니다.
  2. 파일 드롭
    • 외부 파일을 ListBox에 드롭하면 파일 이름이 추가됩니다.
  3. 텍스트 드롭
    • 외부 텍스트를 TextBox에 드롭하면 텍스트가 표시됩니다.

7. 주요 개념 요약

  1. Drag & Drop 동작 과정: DragEnter, DragDrop 이벤트를 통해 데이터를 드래그하고 처리.
  2. AllowDrop 속성: 드롭을 허용하려면 해당 속성을 true로 설정.
  3. e.Data.GetData: 드래그된 데이터를 가져오기 위해 사용.