Directory Tree View サンプルからの改良点 (Dkさんのコメント) |
/// ★入門コードで作るエクスプローラの雛形
/// TreeViewとListViewによるディレクトリとファイルの一覧のサンプル
///
/// サンプルからの改良点
/// ・WinXPでCドライブの「System Volume Infomation」フォルダ以降が表示されない
/// (私の環境固有の不具合か?そもそも「System Volume Infomation」って??)
///
/// ・ファルダアイコンに開くアイコンを追加
/// ImageListの設定
/// 0 = フロッピーディスクアイコン
/// 1 = ドライブアイコン
/// 2 = 閉じたフォルダアイコン
/// 3 = 開いたフォルダアイコン
/// ※アイコンはshell32.dllから抽出
///
/// ・Splitterの追加(TreeViewのDockをLeft、ListViewのDockをFillに設定)
///
/// ・選択フォルダ内のファイル一覧をListViewに表示
///
/// ・選択フォルダの絶対パスをStatusBarに表示
///
/// ・選択ファイルの絶対パスをStatusBarに表示
///
/// ・選択ファイルの起動(指定アプリケーションにてProcess.Start())
///
/// ・動作に影響のない(と思われる)コードを極力排除(ええんかなぁ?)
|
コメント |
Dkさん >> サンプルで、アクセスエラーフォルダ以降が表示されない。
Dkさん >> 原因:「System Volume
Infomation」のアクセスエラーでcatchされるとforeachから抜けてしまう
Dkさん >> (私の環境固有の現象?)
Dkさん >> 解決:この特定フォルダを回避するのではなく、try,catchをforeach内で処理
>> 自分の環境だとアクセスできてしまうので、気がつきませんでした。^^;
>> Dk さんのように try catch でステータスバーに表示するほうがスマートですね。 |
Dkさん >> 動作に影響のない(と思われる)コードを極力排除(ええんかなぁ?)
>> BeginUpdate(), EndUpdate() は、自分の試した範囲でもほとんど効果がないので、
>> なしでOKだと思います。
>> Directory Tree Viewの
selectedDir.Refresh(); も不要ですね ^ ^; 汗。
|
2002/9/22 version
の障害(Dkさんからのレポート) |
現在の 2002/9/22 version では、Cドライブ直下のファイルを選択する場合に
\マークがダブってしまう障害があるという報告がありました。
以下、Dk さんからのメイル(2002/11/13受信)の抜粋です。
-----------------------------------------
Cドライブ直下のファイルを選択する場合に\マークがダブってます(笑
listView1_Clickは↓ですね。
private void listView1_Click(object sender, System.EventArgs e)
{
string s1,s2,s3;
if( treeView1.SelectedNode.FullPath.Length <= 3 )
{
s1 = treeView1.SelectedNode.FullPath.Substring(0,3);
s2 = treeView1.SelectedNode.FullPath.Substring(3,(treeView1.SelectedNode.FullPath.Length - 3));
s3 = listView1.SelectedItems[0].Text;
//★Cドライブ直下のファイルを選択する場合は\を付けなくてよい。
}
else
{
s1 = treeView1.SelectedNode.FullPath.Substring(0,3);
s2 = treeView1.SelectedNode.FullPath.Substring(4,(treeView1.SelectedNode.FullPath.Length - 4));
s3 = "\\" + listView1.SelectedItems[0].Text;
//★上記以外のファイルを選択する場合は\を付ける。
}
statusBar1.Text = s1 + s2 + s3;
}
|
|
Version 情報 |
2002/9/22 version |
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Diagnostics;
namespace TreeView_by_Dk
{
/// <summary>
///
/// ★入門コードで作るエクスプローラの雛形
/// TreeViewとListViewによるディレクトリとファイルの一覧のサンプル
///
/// サンプルからの改良点
/// ・WinXPでCドライブの「System Volume Infomation」フォルダ以降が表示されない
/// (私の環境固有の不具合か?そもそも「System Volume Infomation」って??)
///
/// ・ファルダアイコンに開くアイコンを追加
/// ImageListの設定
/// 0 = フロッピーディスクアイコン
/// 1 = ドライブアイコン
/// 2 = 閉じたフォルダアイコン
/// 3 = 開いたフォルダアイコン
/// ※アイコンはshell32.dllから抽出
///
/// ・Splitterの追加(TreeViewのDockをLeft、ListViewのDockをFillに設定)
///
/// ・選択フォルダ内のファイル一覧をListViewに表示
///
/// ・選択フォルダの絶対パスをStatusBarに表示
///
/// ・選択ファイルの絶対パスをStatusBarに表示
///
/// ・選択ファイルの起動(指定アプリケーションにてProcess.Start())
///
/// ・動作に影響のない(と思われる)コードを極力排除(ええんかなぁ?)
///
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.Splitter splitter1;
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.StatusBar statusBar1;
private System.ComponentModel.IContainer components;
public Form1()
{
//
// Windows フォーム デザイナ サポートに必要です。
//
InitializeComponent();
//
// TODO: 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.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.treeView1 = new System.Windows.Forms.TreeView();
this.splitter1 = new System.Windows.Forms.Splitter();
this.listView1 = new System.Windows.Forms.ListView();
this.statusBar1 = new System.Windows.Forms.StatusBar();
this.SuspendLayout();
//
// 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;
//
// treeView1
//
this.treeView1.Dock = System.Windows.Forms.DockStyle.Left;
this.treeView1.ImageIndex = -1;
this.treeView1.Name = "treeView1";
this.treeView1.SelectedImageIndex = -1;
this.treeView1.Size = new System.Drawing.Size(121, 273);
this.treeView1.TabIndex = 0;
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
this.treeView1.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.treeView1_BeforeExpand);
//
// splitter1
//
this.splitter1.Location = new System.Drawing.Point(121, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 273);
this.splitter1.TabIndex = 1;
this.splitter1.TabStop = false;
//
// listView1
//
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listView1.Location = new System.Drawing.Point(124, 0);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(168, 273);
this.listView1.TabIndex = 2;
this.listView1.View = System.Windows.Forms.View.List;
this.listView1.Click += new System.EventHandler(this.listView1_Click);
this.listView1.DoubleClick += new System.EventHandler(this.listView1_DoubleClick);
//
// statusBar1
//
this.statusBar1.Location = new System.Drawing.Point(124, 251);
this.statusBar1.Name = "statusBar1";
this.statusBar1.Size = new System.Drawing.Size(168, 22);
this.statusBar1.TabIndex = 3;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.statusBar1,
this.listView1,
this.splitter1,
this.treeView1});
this.Name = "Form1";
this.Text = "TreeView_by_Dk";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
treeView1.ImageList = imageList1;//使用するImageListを指定
string[] drives = Environment.GetLogicalDrives();//ドライブ取得
foreach(string drive in drives)
{
TreeNode tn = new TreeNode(drive);
if (drive == "A:\\") //ドライブに対しImageListの画像を指定
{
tn.ImageIndex = 0;
tn.SelectedImageIndex = 0;
}
else
{
tn.ImageIndex = 1;
tn.SelectedImageIndex = 1;
}
treeView1.Nodes.Add(tn);
tn.Nodes.Add("dummy");
//Cドライブを初期展開する場合このコードを追加
//if(tn.Text == "C:\\")
// tn.Expand();
}
}
private void treeView1_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
{
//サンプルで、アクセスエラーフォルダ以降が表示されない。
//原因:「System Volume Infomation」のアクセスエラーでcatchされるとforeachから抜けてしまう
//(私の環境固有の現象?)
//解決:この特定フォルダを回避するのではなく、try,catchをforeach内で処理
//
//BeginUpdate(),EndUpdate()はdummyフォルダを作成するこの方法では不要?
//表示するとき下位フォルダがdummyの1つしか追加されないので負担がかからない?
TreeNode selectedNode = e.Node; //引数のイベント発生ノードに対し追加・削除・複製
selectedNode.Nodes.Clear(); //ダミーノードをクリアするので必要
DirectoryInfo selectedDir = new DirectoryInfo(selectedNode.FullPath);//using System.IO
if (selectedDir.Exists) //ディレクトリが存在すればノードに追加
{
DirectoryInfo[] subDirInfo = selectedDir.GetDirectories();
foreach(DirectoryInfo di in subDirInfo)
{
try
{
TreeNode nd = selectedNode.Nodes.Add(di.Name);//サブディレクトリをノードに追加
nd.ImageIndex = 2; //閉じたフォルダアイコン指定
nd.SelectedImageIndex = 3; //開いたフォルダアイコン指定
DirectoryInfo[] subSubInfo = di.GetDirectories();
if(subSubInfo.Length > 0) //下位にディレクトリがあれば
{
nd.Nodes.Add("dummy"); //+を表示するためにダミーノード(フォルダ)追加
}
}
catch (Exception exc)
{
string s = exc.Message.ToString();
statusBar1.Text = s; //statusBarにエラーを表示
}
}
}
else
{
MessageBox.Show( selectedDir.Root.Name + "にディスクを挿入してください。",
this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
//ListViewにファイル一覧を表示
listView1.Clear();//これがないとファイル表示が累積
DirectoryInfo di = new DirectoryInfo(e.Node.FullPath);
if(e.Node.Text != "A:\\")//+マークによるノード展開でデフォルトのA:\アクセス回避
{
if(di.Exists)
{
try
{
foreach(FileInfo file in di.GetFiles())
{
listView1.Items.Add(file.Name);
}
}
catch (Exception exc)
{
MessageBox.Show( exc.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
statusBarTextShow(e);//★statusBarにFullPathを表示する下記メソッド
}
private void statusBarTextShow(System.Windows.Forms.TreeViewEventArgs e)
{
//★statusBarにフォルダ名までのFullPathを表示
//
//statusBar1.Text = e.Node.FullPath;とすると、
//Environment.GetLogicalDrives()を使うと取得ドライブ名に\マークが付き(例:C:\)、
//FullPathを取得すると\マークが付く(例:\WINDOWS)ので、
//statusBar1.TextにFullPathを入れると「C:\\WINDOWS」となってしまう。。。
//ちなみに、
//string s1 = e.Node.FullPath.Substring(0,2);
//string s2 = e.Node.FullPath.Substring(3,(e.Node.FullPath.Length - 3));
//statusBar1.Text = s1 + s2;
//これではドライブ初期表示に\マークが表示されない(例:C:)
string s1,s2;
if( e.Node.FullPath.Length <= 3 )
{
s1 = e.Node.FullPath.Substring(0,3);
s2 = e.Node.FullPath.Substring(3,(e.Node.FullPath.Length - 3));
//s2は、s2 = ""; のことです。
}
else
{
s1 = e.Node.FullPath.Substring(0,3);
s2 = e.Node.FullPath.Substring(4,(e.Node.FullPath.Length - 4));
}
statusBar1.Text = s1 + s2;
}
private void listView1_Click(object sender, System.EventArgs e)
{
//statusBarにファイル名までのFullPathを表示
string s1,s2,s3;
if( treeView1.SelectedNode.FullPath.Length <= 3 )
{
s1 = treeView1.SelectedNode.FullPath.Substring(0,3);
s2 = treeView1.SelectedNode.FullPath.Substring(3,(treeView1.SelectedNode.FullPath.Length - 3));
//s2は、s2 = ""; のことです。
}
else
{
s1 = treeView1.SelectedNode.FullPath.Substring(0,3);
s2 = treeView1.SelectedNode.FullPath.Substring(4,(treeView1.SelectedNode.FullPath.Length - 4));
}
s3 = "\\" + listView1.SelectedItems[0].Text;
statusBar1.Text = s1 + s2 + s3;
}
private void listView1_DoubleClick(object sender, System.EventArgs e)
{
//listView1の選択ファイルのダブルクリックで関連付けられたアプリ起動
//using System.Diagnosticsが必要
Process.Start(statusBar1.Text);
}
}
}
|