宇宙仮面の
C# Programming

 
Image

フォルダーを選択するダイアログ(TreeView)


開発環境: Visual Studio 2002

注意:いまでは、標準でフォルダーを選択するダイアログがサポートされているので、わざわざこのようなことをする必要はありません。

次のような論理ドライブ以下のディレクトリを TreeView で表示するのForm アプリケーションを作る。

ディレクトリを指定するツールを作りたいのであれば、こちらを参照してください。

入門コードで作るエクスプローラの雛形は、Dk さん作成のTreeViewとListViewによるディレクトリとファイルの一覧を参照してください。

Image
作り方
  1. TreeView を貼り付ける。
  2. ImageList を貼り付ける。
  3. 新しい項目の追加により、フロッピー、ディスク、フォルダー用のビットマップを追加、。
  4. ImageList に、フロッピー、ディスク、フォルダーのビットマップを ImageList に登録する。
Image

論理ドライブの取得方法

string[] drives = System.IO.Directory.GetLogicalDrives();

foreach(string drive in drives)
{
        TreeNode node = this.treeView1.Nodes.Add(drive);
}
このように、BeginUpdate(), EndUpdate(), AddRange を使うと、高速化できる。
しかし、BeginUpdate(), EndUpdate()を使ったところ、かえって表示がちらついてしまった。
ある程度、追加するノードが多い場合に有効か?
   // ちらつきを抑えるために画面の更新を停止する。
   treeView1.BeginUpdate();

   treeView1.Nodes.AddRange(...);

   // 画面の更新を再開
   treeView1.EndUpdate();
以下ソースコード。

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace TestFile
{
        /// <summary>
        /// Form1 の概要の説明です。
        /// </summary>
        public class Form1 : System.Windows.Forms.Form
        {
                private System.Windows.Forms.TreeView treeView1;
                private System.Windows.Forms.ImageList imageList1;
                private System.ComponentModel.IContainer components;

                public Form1()
                {
                        //
                        // Windows フォーム デザイナ サポートに必要です。
                        //
                        InitializeComponent();
                }

                /// <summary>
                /// 使用されているリソースに後処理を実行します。
                /// </summary>
                protected override void Dispose( bool disposing )
                {
                        if( disposing )
                        {
                                if (components != null) 
                                {
                                        components.Dispose();
                                }
                        }
                        base.Dispose( disposing );
                }

                #region Windows Form Designer generated code
                /// <summary>
                /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
                /// コード エディタで変更しないでください。
                /// </summary>
                private void InitializeComponent()
                {
                        this.components = new System.ComponentModel.Container();
                        System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
                        this.treeView1 = new System.Windows.Forms.TreeView();
                        this.imageList1 = new System.Windows.Forms.ImageList(this.components);
                        this.SuspendLayout();
                        // 
                        // treeView1
                        // 
                        this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
                        this.treeView1.HotTracking = true;
                        this.treeView1.ImageList = this.imageList1;
                        this.treeView1.Name = "treeView1";
                        this.treeView1.Size = new System.Drawing.Size(344, 262);
                        this.treeView1.TabIndex = 0;
                        this.treeView1.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.BeforeExpand);
                        // 
                        // imageList1
                        // 
                        this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
                        this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
                        this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
                        this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
                        // 
                        // Form1
                        // 
                        this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
                        this.ClientSize = new System.Drawing.Size(344, 262);
                        this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                                                                                                  this.treeView1});
                        this.Name = "Form1";
                        this.Text = "Directory Tree";
                        this.Activated += new System.EventHandler(this.OnActivated);
                        this.ResumeLayout(false);

                }
                #endregion

                /// <summary>
                /// アプリケーションのメイン エントリ ポイントです。
                /// </summary>
                [STAThread]
                static void Main() 
                {
                        Application.Run(new Form1());
                }

                private enum ImageList { Floppy = 0, Drive = 1, Folder = 2};

                static private bool notInitialized = true;

                private void OnActivated(object sender, System.EventArgs e)
                {
                        if(notInitialized)
                        {
                                SetDrives(e);
                                notInitialized = false;
                        }
                }

                // 初期起動時に、トップノードに論理ドライブを追加する。
                private void SetDrives(System.EventArgs e)
                {
                        try 
                        {
                                // 論理ドライブの取得
                                string[] drives = Directory.GetLogicalDrives();
                                // ツリーのクリアをしておく。
                                this.treeView1.Nodes.Clear();
                                // すべての論理ドライブに対して
                                foreach(string drive in drives) 
                                {
                                        // TreeView のトップノードに論理ドライブを追加する。
                                        TreeNode node = this.treeView1.Nodes.Add(drive);
                                        if (drive == "A:\\") 
                                        {
                                                // ImageListの画像を指定する。
                                                node.ImageIndex = (int)ImageList.Floppy;
                                                node.SelectedImageIndex = (int)ImageList.Floppy;
                                        }
                                        else 
                                        {
                                                // ImageListの画像を指定する。
                                                node.ImageIndex = (int)ImageList.Drive;
                                                node.SelectedImageIndex = (int)ImageList.Drive;
                                        }
                                        //  ドライブのノードに+を表示するためにダミーノードを追加する。
                                        node.Nodes.Add("dummy");
                                }
                        } 
                        catch (Exception exc)
                        {
                                MessageBox.Show( exc.Message,
                                        this.Text,
                                        MessageBoxButtons.OK, 
                                        MessageBoxIcon.Exclamation);
                        }
                }

                private void BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
                {
                        // サブツリー
                        this.ShowSubTrees(e);           
                }

                // Node が Expand されたときに呼び出す。
                // サブディレクトリが存在すれば、ノードを追加する。
                private void ShowSubTrees(System.Windows.Forms.TreeViewCancelEventArgs e)
                {
                        try
                        {
                                TreeNode selectedNode = e.Node;
                                // ダミーノードをクリアする。
                                selectedNode.Nodes.Clear();
                                DirectoryInfo selectedDir = new DirectoryInfo( selectedNode.FullPath );
                                selectedDir.Refresh();
                                // ディレクトリが存在すれば、ノードを追加する。
                                if (selectedDir.Exists) 
                                {
                                        DirectoryInfo[] subDirInfo = selectedDir.GetDirectories();
                                        foreach (DirectoryInfo di in subDirInfo)
                                        {
                                                // サブディレクトリをノードに追加する。
                                                TreeNode nd = selectedNode.Nodes.Add(di.Name);
                                                // ImageListの画像を指定する。
                                                nd.ImageIndex = (int)ImageList.Folder;
                                                nd.SelectedImageIndex = (int)ImageList.Folder;
                                                //  下位にディレクトリがあれば+を表示するためにダミーノードを追加する。
                                                DirectoryInfo[] subSubInfo = di.GetDirectories();
                                                if(subSubInfo.Length > 0)
                                                        nd.Nodes.Add("dummy");
                                        }
                                }
                                else
                                {
                                        MessageBox.Show( selectedDir.Root.Name + "にディスクを挿入してください。",
                                                this.Text,
                                                MessageBoxButtons.OK, 
                                                MessageBoxIcon.Exclamation);
                                }
                        }
                        catch (Exception exc)
                        {
                                MessageBox.Show( exc.Message,
                                 this.Text,
                                 MessageBoxButtons.OK, 
                                 MessageBoxIcon.Exclamation);
                        }
                }
        }
}