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

C# WinForms 實現檔案拖放 (Drag & Drop) 完整教學

     編輯:關於C#

在 WinForms 應用中實現類似檔案總管的拖放體驗,包含從外部拖入檔案到應用程式與從應用程式拖出檔案到外部。本文提供逐步實作指南與完整程式碼。

環境準備

  • 在 Form 上放置一個 ListView (listViewFolder) 並設定:View = View.Details、AllowDrop = true。
  • 加入 Label (labelCurFolder) 顯示目前資料夾路徑。

步驟 1:列出資料夾檔案

private void ListFolder(string directory)
{
    labelCurFolder.Text = directory;
    listViewFolder.Items.Clear();
    listViewFolder.Columns.Clear();
    listViewFolder.Columns.Add("Name", 300);
    listViewFolder.Columns.Add("Size", 100);
    listViewFolder.Columns.Add("Time", 200);

    string[] files = Directory.GetFiles(directory);
    foreach (string file in files)
    {
        var item = new ListViewItem(Path.GetFileName(file));
        item.Tag = file; // 存儲完整路徑供拖放使用

        // 圖示處理 (略,可使用 Icon.ExtractAssociatedIcon)
        // item.ImageIndex = ...

        FileInfo fi = new FileInfo(file);
        item.SubItems.Add(FormatFileSize(fi.Length));
        item.SubItems.Add(fi.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"));

        listViewFolder.Items.Add(item);
    }
}

private string FormatFileSize(long bytes)
{
    if (bytes < 1024) return $"{bytes} B";
    if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB";
    if (bytes < 1024 * 1024 * 1024) return $"{bytes / (1024.0 * 1024):F1} MB";
    return $"{bytes / (1024.0 * 1024 * 1024):F1} GB";
}

步驟 2:實現拖入 (DragEnter + DragDrop)

private void listViewFolder_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
        e.Effect = DragDropEffects.Copy;
    else
        e.Effect = DragDropEffects.None;
}

private void listViewFolder_DragDrop(object sender, DragEventArgs e)
{
    try
    {
        string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        string targetDir = labelCurFolder.Text;

        foreach (string src in files)
        {
            string dest = Path.Combine(targetDir, Path.GetFileName(src));
            if (File.Exists(dest))
            {
                var result = MessageBox.Show(
                    $"檔案 {Path.GetFileName(src)} 已存在,是否取代?",
                    "確認取代", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result != DialogResult.Yes) continue;
            }
            File.Copy(src, dest, true);
        }
        ListFolder(targetDir); // 重新整理列表
    }
    catch (Exception ex)
    {
        MessageBox.Show($"拷貝失敗: {ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

步驟 3:實現拖出 (ItemDrag + DoDragDrop)

private void listViewFolder_ItemDrag(object sender, ItemDragEventArgs e)
{
    if (e.Button != MouseButtons.Left) return;
    if (listViewFolder.SelectedItems.Count == 0) return;

    // 收集選取項目的完整路徑
    string[] files = new string[listViewFolder.SelectedItems.Count];
    for (int i = 0; i < files.Length; i++)
        files[i] = listViewFolder.SelectedItems[i].Tag.ToString();

    // 建立 DataObject 並啟動拖放
    DataObject data = new DataObject(DataFormats.FileDrop, files);
    data.SetData(DataFormats.StringFormat, files[0]); // 兼容僅支援文字的目標
    DoDragDrop(data, DragDropEffects.Copy);
}

完整事件綁定 (Form Load 或建構式)

listViewFolder.DragEnter += listViewFolder_DragEnter;
listViewFolder.DragDrop += listViewFolder_DragDrop;
listViewFolder.ItemDrag += listViewFolder_ItemDrag;

關鍵點總結

  • AllowDrop = true 是啟用拖放的前提。
  • DragEnter 判斷資料格式並設定 e.Effect 決定游標樣式。
  • DragDrop 執行實際檔案複製/移動邏輯。
  • ItemDrag 是 ListView 專有事件,適合啟動拖出操作;一般控制項可用 MouseDown + DoDragDrop。
  • DataObject 可同時包含多種格式 (FileDrop, Text, 自訂格式) 提高相容性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved