header
CodePanic! > C#.NET Tips > 今ここ

■エクスプローラーのようなドライブとフォルダのツリーを作る

TreeViewコントロールを使って
エクスプローラーのようなドライブとフォルダのツリーを作る例です。
treeview_folder.jpg(18863 byte)

すべてのNodeを起動時に列挙、追加するとかなり処理が重くなってしまうため
必要なNodeのみ追加し、下位Nodeは+ボックスをクリックされる都度検索、追加しています。

■InitTree関数
	ここで起動時に論理ドライブの一覧を取得し、TreeViewに登録しています。
	ノードが展開可能であることを表す+ボックスを表示させるために
	文字列dummyをダミーで追加しています。
	
■BeforeExpandイベントハンドラ
	+ボックスがクリックされ、Nodeが展開される前に呼び出されます。
	この中でフォルダ内のサブフォルダ一覧を取得し、追加しています。

なお、これは必須ではないのですが
ドライブの種類に応じたアイコンや
フォルダの選択時、非選択時のアイコンを表示するために
次のようなImageListを準備し、TreeViewのImageListプロパティーに設定しています。
treeview_imagelist.jpg(92631 byte)

また、ドライブの種別を取得するために
参照設定にSystem.Managementを追加しています。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Management;    // 参照設定に追加を忘れずに
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            treeView1.BeforeExpand += new TreeViewCancelEventHandler(treeView1_BeforeExpand);
            treeView1.Dock = DockStyle.Fill;
            treeView1.ImageList = this.imageList1;
            treeView1.Sorted = true;	// ※文字列順に自動Sortします。

            InitTree();
        }

        private void InitTree()
        {
            ManagementObject mo = new ManagementObject();

            // 論理ドライブ一覧を列挙
            string[] drives = Environment.GetLogicalDrives();
            foreach (string drive in drives)
            {
                // ドライブのタイプを取得
                mo.Path = new ManagementPath("Win32_LogicalDisk='" + drive.TrimEnd('\\') + "'");
                int drivetype = Convert.ToInt32(mo.Properties["DriveType"].Value);

                // ドライブのタイプごとにアイコンを設定
                TreeNode node = new TreeNode();
                switch (drivetype)
                {
                    case 0:
                        //ドライブを判別できません
                        continue;
                        break;
                    case 1:
                        //ドライブ上にルートディレクトリが存在しません
                        continue;
                        break;
                    case 2:
                        //Floppy
                        node = new TreeNode(drive, 4, 4);
                        break;
                    case 3:
                    case 6:
                        //HardDisk
                        node = new TreeNode(drive, 0, 0);
                        break;
                    case 4:
                        //Network
                        node = new TreeNode(drive, 5, 5);
                        break;
                    case 5:
                        //CD-ROM
                        node = new TreeNode(drive, 3, 3);
                        break;
                }

                treeView1.Nodes.Add(node);

                // +ボックスを表示するためのダミー
                node.Nodes.Add("dummy");
            }
        }


        void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            TreeNode node = e.Node;

            // 展開するノードのフルパスを取得
            string fullpath = node.FullPath;
            node.Nodes.Clear();

            // フォルダ一覧を取得
            DirectoryInfo dirs = new DirectoryInfo(fullpath);
            try
            {
                foreach (DirectoryInfo dir in dirs.GetDirectories())
                {
                    // フォルダを追加
                    TreeNode nodeFolder = new TreeNode(dir.Name, 1, 2);
                    node.Nodes.Add(nodeFolder);

                    // +ボックスを表示するためのダミー
                    nodeFolder.Nodes.Add("dummy");
                }
            }
            catch { }
        }
    }
}





Copyright © 2008.07 - shougo suzaki