C# 將內容、檔案拖曳至 WinForm 應用程式中 教學

很多軟體都支援「拖曳」的功能,例如把 HTML 檔案拖曳至瀏覽器中,瀏覽器就會自動開啟該檔案,並且顯示檔案內容。那在 WinForm 中該如何實作呢?

最簡單實作拖曳文字功能

其實只要三步驟:
  1. AllowDrop = true
  2. DragEnter 事件判斷拖曳內容類型
  3. DragDrop 事件取得實際資料
    public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.AllowDrop = true; // 啟用拖曳功能
        this.DragEnter += new DragEventHandler(Form1_DragEnter);
        this.DragDrop += new DragEventHandler(Form1_DragDrop);
    }

    /// <summary>
    /// 滑鼠拖曳進入視窗,判斷內容類型決定是否開放拖曳功能
    /// </summary>
    private void Form1_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data == null) return;

		// 取得
        string[] formats = { DataFormats.Text, DataFormats.UnicodeText, DataFormats.Html, DataFormats.Rtf };
        if (formats.Any(format => e.Data.GetDataPresent(format)))
        {
            e.Effect = DragDropEffects.Copy;
        }
    }

    /// <summary>
    /// 滑鼠放開,取得拖曳的資料
    /// </summary>
    private void Form1_DragDrop(object sender, DragEventArgs e)
    {
        try
        {
            if (e.Data == null) return;
            
            string[] formats = { DataFormats.Text, DataFormats.UnicodeText, DataFormats.Html, DataFormats.Rtf };
            foreach (string format in formats)
            {
                if (e.Data.GetDataPresent(format))
                {
                    string data = (string)e.Data.GetData(format);
                    // 處理資料
                    Log.Information($"data: {data}");
                    break;
                }
            }
            
        }
        catch (Exception exception)
        {
            Log.Error(exception, "DragDrop Error");
        }
    }
}
    

註: 本文中的 Log 是使用 Serilog 套件輸出 log
延伸閱讀: C# 使用 Serilog 紀錄 Log (不用設定檔)

拖曳檔案示範

拖曳檔案只能取得檔案路徑,不能直接取得檔案內容
    
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.AllowDrop = true; // 啟用拖曳功能
        this.DragEnter += new DragEventHandler(Form1_DragEnter);
        this.DragDrop += new DragEventHandler(Form1_DragDrop);
    }

    /// <summary>
    /// 滑鼠拖曳進入視窗,判斷內容類型決定是否開放拖曳功能
    /// </summary>
    private void Form1_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data == null) return;

        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            e.Effect = DragDropEffects.Copy;
        }
    }

    /// <summary>
    /// 滑鼠放開,取得拖曳的資料
    /// </summary>
    private void Form1_DragDrop(object sender, DragEventArgs e)
    {
        try
        {
            if (e.Data == null) return;

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop);
                // 輸出所有路徑。
                paths.ToList().ForEach(path => Log.Information($"data: {path}"));
            }
        }
        catch (Exception exception)
        {
            Log.Error(exception, "DragDrop Error");
        }
    }
}
    

e.Effect 可以設定的內容有以下幾種:
  • None: 游標顯示禁止的符號,不能拖曳
  • Scroll: 游標顯示禁止的符號,測試時拖曳會有資料
  • Move: 游標顯示方框
  • Link: 游標顯示連結
  • Copy: 游標顯示方框再加上加號
  • All: 游標顯示方框再加上加號


參考資料:
Microsoft.Learn - Walkthrough: Performing a Drag-and-Drop Operation in Windows Forms
StackOverflow - How do I drag and drop files into an application?
StackOverflow - Drag and Drop ListBoxItems generically

留言