|
フォルダーを選択するダイアログ(TreeView)
|
開発環境: Visual Studio 2002
注意:いまでは、標準でフォルダーを選択するダイアログがサポートされているので、わざわざこのようなことをする必要はありません。
次のような論理ドライブ以下のディレクトリを TreeView で表示するのForm アプリケーションを作る。
ディレクトリを指定するツールを作りたいのであれば、こちらを参照してください。
入門コードで作るエクスプローラの雛形は、Dk さん作成のTreeViewとListViewによるディレクトリとファイルの一覧を参照してください。
作り方
- TreeView を貼り付ける。
- ImageList を貼り付ける。
- 新しい項目の追加により、フロッピー、ディスク、フォルダー用のビットマップを追加、。
- ImageList に、フロッピー、ディスク、フォルダーのビットマップを ImageList に登録する。
論理ドライブの取得方法
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);
}
}
}
}