MouseDown 事件中呼叫 DoDragDrop()DragEnter 事件中檢查資料格式,設定 DragDropEffectsDragDrop 事件中取得資料並更新 UIusing System;
using System.Windows.Forms;
namespace DragDropDemo
{
public class MainForm : Form
{
private ListBox listBoxSource;
private ListBox listBoxTarget;
public MainForm()
{
InitializeComponent();
SetupDragDrop();
}
private void InitializeComponent()
{
this.listBoxSource = new ListBox();
this.listBoxTarget = new ListBox();
this.SuspendLayout();
// 來源 ListBox
this.listBoxSource.ItemHeight = 16;
this.listBoxSource.Location = new System.Drawing.Point(32, 24);
this.listBoxSource.Name = "listBoxSource";
this.listBoxSource.Size = new System.Drawing.Size(150, 280);
this.listBoxSource.TabIndex = 0;
this.listBoxSource.MouseDown += ListBoxSource_MouseDown;
this.listBoxSource.AllowDrop = true; // 允許作為放置目標(可選)
// 目標 ListBox
this.listBoxTarget.ItemHeight = 16;
this.listBoxTarget.Location = new System.Drawing.Point(248, 24);
this.listBoxTarget.Name = "listBoxTarget";
this.listBoxTarget.Size = new System.Drawing.Size(150, 280);
this.listBoxTarget.TabIndex = 1;
this.listBoxTarget.DragEnter += ListBoxTarget_DragEnter;
this.listBoxTarget.DragDrop += ListBoxTarget_DragDrop;
this.listBoxTarget.AllowDrop = true; // 必須設定 true 才能接收放置
// Form
this.ClientSize = new System.Drawing.Size(450, 350);
this.Controls.Add(this.listBoxSource);
this.Controls.Add(this.listBoxTarget);
this.Name = "MainForm";
this.Text = "拖放示範";
this.Load += MainForm_Load;
this.ResumeLayout(false);
}
private void MainForm_Load(object sender, EventArgs e)
{
listBoxSource.Items.AddRange(new object[] { "項目 A", "項目 B", "項目 C", "項目 D" });
}
// 步驟 1:啟動拖放
private void ListBoxSource_MouseDown(object sender, MouseEventArgs e)
{
ListBox lb = (ListBox)sender;
int index = lb.IndexFromPoint(e.Location);
if (index >= 0)
{
object item = lb.Items[index];
// Move 表示移動(來源會移除),Copy 表示複製
lb.DoDragDrop(item, DragDropEffects.Move);
}
}
// 步驟 2:設定拖放效果
private void ListBoxTarget_DragEnter(object sender, DragEventArgs e)
{
// 僅接受文字格式資料
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Move;
else
e.Effect = DragDropEffects.None;
}
// 步驟 3:完成放置
private void ListBoxTarget_DragDrop(object sender, DragEventArgs e)
{
ListBox target = (ListBox)sender;
if (e.Data.GetDataPresent(DataFormats.Text))
{
string text = (string)e.Data.GetData(DataFormats.Text);
target.Items.Add(text);
// 移除來源項目(Move 效果需自行處理)
listBoxSource.Items.Remove(text);
}
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
不限於字串,任何可序列化物件皆可拖放:
// 來源
var customer = new Customer { Id = 1, Name = "張三" };
lb.DoDragDrop(customer, DragDropEffects.Move);
// 目標
if (e.Data.GetDataPresent(typeof(Customer)))
{
Customer c = (Customer)e.Data.GetData(typeof(Customer));
targetList.Items.Add(c.Name);
}
private void ListBoxTarget_DragOver(object sender, DragEventArgs e)
{
// 根據滑鼠位置決定是插入還是附加
ListBox lb = (ListBox)sender;
int index = lb.IndexFromPoint(lb.PointToClient(new Point(e.X, e.Y)));
if (index >= 0)
lb.SelectedIndex = index; // 視覺提示插入位置
}
AllowDrop = true 即可接收來自其他應用程式(如檔案總管、瀏覽器)的拖放DataFormats.FileDrop,取得 string[] 路徑陣列| 屬性/方法 | 用途 | 備註 |
|---|---|---|
Control.AllowDrop | 啟用控制項接收拖放 | 目標控制項必須設為 true |
DoDragDrop(data, effects) | 啟動拖放作業 | 來源控制項呼叫 |
DragEventArgs.Data | 取得拖放資料物件 | 實作 IDataObject |
DragEventArgs.Effect | 設定/取得拖放效果 | Move, Copy, Link, None |
DragDropEffects | 列舉拖放效果類型 | Move=移動, Copy=複製 |