首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# WinForms 拖放功能實作:三步驟完成 ListBox 項目移動

     編輯:關於C語言

拖放操作核心三步驟

  1. 啟動拖放:來源控制項 MouseDown 事件中呼叫 DoDragDrop()
  2. 設定拖放效果:目標控制項 DragEnter 事件中檢查資料格式,設定 DragDropEffects
  3. 完成放置:目標控制項 DragDrop 事件中取得資料並更新 UI

完整程式碼範例

using 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=複製
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved