2019-08-01に投稿

【C#】ListViewの項目を別のListViewへ追加する

今回は ListViewに表示したフォルダ、ファイルを別の ListView に移す(コピー)してみたいと思います。

プログラムは前回のものを流用します。

【C#】TreeViewとListViewにシステムイメージ(アイコン)を表示する

画面修正

画面の修正

「追加」、「削除」、「追加項目をクリア」ボタンと、別のListViewを追加します。
ボタンにはそれぞれ「Click」イベントを追加。

プログラム修正

既存処理の修正

起動時の処理時に、追加したListViewのイメージリスト、ヘッダーを設定します。

        /// <summary>
        /// 起動時の処理
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            // イメージリストの設定
            SHFILEINFO shFileInfo = new SHFILEINFO();
            IntPtr imageListHandle = SHGetFileInfo(String.Empty, 0, out shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
            // TreeView
            SendMessage(treeView1.Handle, TVM_SETIMAGELIST, new IntPtr(TVSIL_NORMAL), imageListHandle);
            // ListViewFrom
            SendMessage(listView1.Handle, LVM_SETIMAGELIST, new IntPtr(LVSIL_SMALL), imageListHandle);
            // ListViewTo
            SendMessage(listViewTo.Handle, LVM_SETIMAGELIST, new IntPtr(LVSIL_SMALL), imageListHandle);

            // ドライブ一覧を走査してツリーに追加
            foreach (String drive in Environment.GetLogicalDrives())
            {
                // アイコンの取得
                int iconIndex = 0;
                IntPtr hSuccess = SHGetFileInfo(drive, 0, out shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_SYSICONINDEX );
                if (hSuccess != IntPtr.Zero)
                {
                    iconIndex = shFileInfo.iIcon;
                }

                // 新規ノード作成
                // プラスボタンを表示するため空のノードを追加しておく
                TreeNode node = new TreeNode(drive, iconIndex, iconIndex);
                node.Nodes.Add(new TreeNode());
                treeView1.Nodes.Add(node);
            }

            // 初期選択ドライブの内容を表示
            setListItem(Environment.GetLogicalDrives().First());

            // リストビューのヘッダーを設定
            listViewTo.View = View.Details;
            listViewTo.Clear();
            listViewTo.Columns.Add("名前");
            listViewTo.Columns.Add("種類");
            listViewTo.Columns.Add("更新日時");
            listViewTo.Columns.Add("サイズ");
        }

また、追加する項目が既に別のListViewに存在するかどうかチェックするため
ファイル・フォルダのフルパスをListViewItemに持たせるように修正します。
(リストビューの項目設定処理)

            /// <summary>
            /// リストビューの項目を設定します.
            /// </summary>
            private void setListItem(String filePath)
            {
                // リストビューのヘッダーを設定
                listView1.View = View.Details;
                listView1.Clear();
                listView1.Columns.Add("名前");
                listView1.Columns.Add("種類");
                listView1.Columns.Add("更新日時");
                listView1.Columns.Add("サイズ");

                try
                {
                    // フォルダ一覧
                    DirectoryInfo dirList = new DirectoryInfo(filePath);
                    foreach (DirectoryInfo di in dirList.GetDirectories())
                    {
                        ListViewItem item = new ListViewItem(di.Name);

                        // フォルダ種類、アイコンの取得
                        String type = "";
                        int iconIndex = 0;
                        SHFILEINFO shFileInfo = new SHFILEINFO();
                        IntPtr hSuccess = SHGetFileInfo(di.FullName, 0, out shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
                        if (hSuccess != IntPtr.Zero)
                        {
                            type = shFileInfo.szTypeName;
                            iconIndex = shFileInfo.iIcon;
                        }

                        // 各列の内容を設定
                        item.Name = di.FullName;
                        item.ImageIndex = iconIndex;
                        item.SubItems.Add(type);
                        item.SubItems.Add(String.Format("{0:yyyy/MM/dd HH:mm:ss}", di.LastAccessTime));
                        item.SubItems.Add("");

                        // リストに追加
                        listView1.Items.Add(item);

                    }

                    // ファイル一覧
                    List<String> files = Directory.GetFiles(filePath).ToList<String>();
                    foreach (String file in files)
                    {
                        FileInfo info = new FileInfo(file);
                        ListViewItem item = new ListViewItem(info.Name);

                        // ファイル種類、アイコンの取得
                        String type = "";
                        int iconIndex = 0;
                        SHFILEINFO shinfo = new SHFILEINFO();
                        IntPtr hSuccess = SHGetFileInfo(info.FullName, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
                        if (hSuccess != IntPtr.Zero)
                        {
                            type = shinfo.szTypeName;
                            iconIndex = shinfo.iIcon;
                        }

                        // 各列の内容を設定
                        item.Name = info.FullName;
                        item.ImageIndex = iconIndex;
                        item.SubItems.Add(type);
                        item.SubItems.Add(String.Format("{0:yyyy/MM/dd HH:mm:ss}", info.LastAccessTime));
                        item.SubItems.Add(getFileSize(info.Length));
                        listView1.Items.Add(item);
                    }
                }
                catch (IOException ie)
                {
                    MessageBox.Show(ie.Message, "選択エラー");
                }

                // 列幅を自動調整
                listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            }

イベント処理の追加

各ボタンのクリックイベントを追加

            /// <summary>
            /// 追加ボタンクリックイベント.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btn_add_Click(object sender, EventArgs e)
            {
                var selectedItems = listView1.SelectedItems;
                foreach (ListViewItem item in selectedItems)
                {
                    // 項目をコピーして名前を再設定
                    ListViewItem copy = (ListViewItem)item.Clone();
                    copy.Name = item.Name;

                    // 既にリストに含まれていないパスであれば追加
                    if (listViewTo.Items.Find(copy.Name, false).Length == 0)
                    {
                        listViewTo.Items.Add(copy);
                    }
                }

                // 列幅を自動調整
                listViewTo.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            }

            /// <summary>
            /// 削除ボタンクリックイベント.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btn_del_Click(object sender, EventArgs e)
            {
                var selectedItems = listViewTo.SelectedItems;
                foreach (ListViewItem item in selectedItems)
                {
                    listViewTo.Items.Remove(item);
                }

                // 列幅を自動調整
                listViewTo.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

            }

            /// <summary>
            /// 追加項目をクリアボタンクリックイベント
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnClear_Click(object sender, EventArgs e)
            {
                listViewTo.Items.Clear();
            }

起動してみる

項目を選択

追加ボタンを押下

選択した項目を別の ListView に追加することができました。

まとめ

複数のフォルダやファイルに対して何か処理をする際に、ユーザに選ばせるようなイメージですね。
まあよくある感じですか。

次回は選択されたフォルダ・ファイルに対して何かしらの処理をする、などをやってみようかと思います。

ではでは。

 

Originally published at www.doraxdora.com

doraxdora

IT関係の仕事をしています/1985年生まれの東京在住/便利なサービスやツール漁りや料理などが好き/2017年~ブログやってます/自分でサービスとか作ってリリースしたい/何かありましたらお気軽にDMどうぞ

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント