BETA

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

投稿日:2019-08-01
最終更新:2019-08-01
※この記事は外部サイト(https://www.doraxdora.com/blog/2018/02/03/...)からのクロス投稿です

今回は 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 HHss}", 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 HHss}", 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 に追加することができました。

まとめ

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

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

ではでは。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@doraxdoraの技術ブログ 主に Java, C#, Python, Javascript の記事を載せていく予定。

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!