エクスプローラと Drag&Drop

Windows Explorer と Drag&Drop します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

エクスプローラから受取る

  1. ListView を使って Windows Explorer との間で Drag&Drop します。
    Windows Explorer からドラッグされたファイルリストを ListView に追加します。
    /*********************************************/
    /*★ エクスプローラ ⇒ ListView    前田 稔 ★*/
    /*********************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.IO;
    using System.Collections.Generic;
    
    public class MyForm : Form
    {
        private ListView    listView1;
        private Point       mouseDownPoint = Point.Empty;
        private int[]       width = { 240, 120, 80 };
        private string[]    head = { "名前", "更新日付", "サイズ" };
        private string      path = @"C:\TMP";
    
        public MyForm()
        {
            InitializeComponent();
            InitializeListView();
            Load += new System.EventHandler(MyForm_Load);
        }
    
        private void InitializeComponent()
        {
            this.listView1 = new System.Windows.Forms.ListView();
            this.SuspendLayout();
    
            // listView1
            this.listView1.Location = new System.Drawing.Point(12, 12);
            this.listView1.Name = "listView1";
            this.listView1.Size = new System.Drawing.Size(460, 380);
            this.listView1.TabIndex = 0;
            this.listView1.UseCompatibleStateImageBehavior = false;
            this.listView1.AllowDrop = true;
            this.listView1.DragEnter += new DragEventHandler(this.ListView1_DragEnter);
            this.listView1.DragDrop += new DragEventHandler(this.ListView1_DragDrop);
    
            // MyForm
            this.ClientSize = new System.Drawing.Size(480, 400);
            this.Controls.Add(this.listView1);
            this.Name = "MyForm";
            this.ResumeLayout(false);
        }
    
        // ListViewコントロールを初期化します。
        private void InitializeListView()
        {
            // ListViewコントロールのプロパティを設定
            listView1.FullRowSelect = true;
            listView1.GridLines = true;
            listView1.View = View.Details;
    
            // 列ヘッダの作成
            ColumnHeader[] columnHead = new ColumnHeader[3];
            for (int i=0; i<3; i++)
            {   columnHead[i] = new ColumnHeader();
                columnHead[i].Width = width[i];
                columnHead[i].Text = head[i];
            }
            listView1.Columns.AddRange(columnHead);
        }
    
        // ListViewコントロールのデータを更新します。
        private void MyForm_Load(object sender, System.EventArgs e)
        {
            //DirectoryInfoを作成
            DirectoryInfo di = new DirectoryInfo(path);
            string[] item = new string[3];
    
            //ファイル一覧の取得
            FileInfo [] fis = di.GetFiles("*.*");
            for( int i=0;i<fis.Length;i++)
            {   item[0]= fis[i].FullName;
                item[1]= fis[i].LastWriteTime.ToString();
                item[2]= fis[i].Length.ToString();
                listView1.Items.Add(new ListViewItem(item));
            }
        }
    
        // Drop の開始
        private void ListView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
        }
    
        // DataObject を string の配列で受け取る
        private void ListView1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                foreach(string fileName in (string[])e.Data.GetData(DataFormats.FileDrop))
                {   listView1.Items.Add(fileName);  }
            }
        }
    }
    
    class form01
    {
        [STAThread]
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  2. このプログラムを起動すると @"C:\TMP" のフォルダを検索してファイル一覧を ListView に表示します。
    事前に @"C:\TMP" に適当なファイルを格納しておいて下さい。
    private string path = @"C:\TMP";
  3. Drag&Drop View では List<T> を使いましたが、 Copy&Paste や Drag&Drop の標準データ形式は IDataObject です。
    Windows Explorer とやり取りするときは IDataObject を使わなければなりません。
    下記のソースでは良く分かりませんが、IDataObject を string[] に変換しています。
        foreach(string fileName in (string[])e.Data.GetData(DataFormats.FileDrop))
        {   listView1.Items.Add(fileName);  }
        
  4. 今回は受け取ったファイルリストを ListView に追加するだけで、実際にファイルがコピーされる訳ではありません。
    実際にコピーする方法は Folder Copy を参照して下さい。

エクスプローラに渡す

  1. エクスプローラに ListView のファイルを渡します。
    /*********************************************/
    /*★ ListView ⇒ エクスプローラ    前田 稔 ★*/
    /*   コピーのときは Crtl を押しながら        */
    /*********************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.IO;
    using System.Collections.Generic;
    
    public class MyForm : Form
    {
        private ListView    listView1;
        private Point       mouseDownPoint = Point.Empty;
        private int[]       width = { 240, 120, 80 };
        private string[]    head = { "名前", "更新日付", "サイズ" };
        private string      path = @"C:\TMP";
    
        public MyForm()
        {
            InitializeComponent();
            Load += new System.EventHandler(MyForm_Load);
        }
    
        private void InitializeComponent()
        {
            this.listView1 = new System.Windows.Forms.ListView();
            this.SuspendLayout();
    
            // listView1
            this.listView1.Location = new System.Drawing.Point(12, 12);
            this.listView1.Name = "listView1";
            this.listView1.Size = new System.Drawing.Size(460, 380);
            this.listView1.TabIndex = 0;
            this.listView1.UseCompatibleStateImageBehavior = false;
            this.listView1.AllowDrop = true;
            this.listView1.ItemDrag += new ItemDragEventHandler(ListView1_ItemDrag);
    
            // MyForm
            this.ClientSize = new System.Drawing.Size(480, 400);
            this.Controls.Add(this.listView1);
            this.Name = "MyForm";
            this.ResumeLayout(false);
        }
    
        // ListViewコントロールを初期化します。
        private void MyForm_Load(object sender, System.EventArgs e)
        {
            // ListViewコントロールのプロパティを設定
            listView1.FullRowSelect = true;
            listView1.GridLines = true;
            listView1.View = View.Details;
    
            // 列ヘッダの作成
            ColumnHeader[] columnHead = new ColumnHeader[3];
            for (int i=0; i<3; i++)
            {   columnHead[i] = new ColumnHeader();
                columnHead[i].Width = width[i];
                columnHead[i].Text = head[i];
            }
            listView1.Columns.AddRange(columnHead);
            ListReset();
        }
    
        // ListView コントロールのデータを更新
        private void ListReset()
        {
            //DirectoryInfoを作成
            DirectoryInfo di = new DirectoryInfo(path);
            string[] item = new string[3];
    
            listView1.Items.Clear();
            //ファイル一覧の取得
            FileInfo [] fis = di.GetFiles("*.*");
            for( int i=0;i<fis.Length;i++)
            {
                item[0]= fis[i].FullName;
                item[1]= fis[i].LastWriteTime.ToString();
                item[2]= fis[i].Length.ToString();
                listView1.Items.Add(new ListViewItem(item));
            }
        }
    
        // DataObject を渡す
        private void ListView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            System.Collections.Specialized.StringCollection files =
                new System.Collections.Specialized.StringCollection();
            for (int i = 0; i < listView1.SelectedItems.Count; i++)
                files.Add(listView1.SelectedItems[i].Text);
            DataObject dataObj = new DataObject();
            dataObj.SetFileDropList(files);
            listView1.DoDragDrop(dataObj, DragDropEffects.All);
            ListReset();
        }
    }
    
    class form01
    {
        [STAThread]
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  2. Drag&Drop View では List<T> を使いましたが、 Copy&Paste や Drag&Drop の標準データ形式は IDataObject です。
    Windows Explorer とやり取りするときは IDataObject を使わなければなりません。
    エクスプローラから受取る場合は ListView に登録されるだけでしたが、渡す場合は実際にファイルがコピー(移動)します。
    単に Drag&Drop するとファイルが移動します。
    Ctrl キーを押しながら Drag&Drop するとファイルがコピーされます。
    Drag&Drop が完了すると ListReset() で最新の状態に更新するのでファイルの移動を確認出来ます。
        // DataObject を渡す
        private void ListView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            System.Collections.Specialized.StringCollection files =
                new System.Collections.Specialized.StringCollection();
            for (int i = 0; i < listView1.SelectedItems.Count; i++)
                files.Add(listView1.SelectedItems[i].Text);
            DataObject dataObj = new DataObject();
            dataObj.SetFileDropList(files);
            listView1.DoDragDrop(dataObj, DragDropEffects.All);
            ListReset();
        }
        
  3. 「エクスプローラから受取る」と「エクスプローラに渡す」を起動してテストして下さい。
    渡す場合は「実際にファイルがコピー(移動)」するので、大切なファイルを無くさないように注意して下さい。
    Ctrl キーを押しながら Drag&Drop するとファイルがコピーされます。
    Windows(C++) でも同様のプログラムを作成しています。
    C++ API で File List を Drag&Drop する を参照して下さい。

【NOTE】

エクスプローラに渡すとき、カレントディレクトリが効いているときは、上記のソースでそのまま動きます。
カレントディレクトリが効いていないときは、フルパスで渡して下さい。
次のソースでは、ファイル名だけが渡されます。
files.Add(listView1.SelectedItems[i].Text);

超初心者のプログラム入門(C# Frame Work)