Introduction
This article describes the implementation of a simple Folder Selection dialog
using C#. After designing my latest project, I found a need for a simple, easy
to implement folder selection dialog for C#. The OpenFileDialog
class
did not suite my needs, and to integrate the COM interface to the SHBrowseForFolder
,
was a little more complicated that the solution I present here.
The basic dialog is built with the standard winform architecture. by
modifying the window style, you can make the dialog appear as a standard windows
dialog, or as a sizable window, which is the default for this example.
this example was put together using Visual Studio .Net beta 2, and the IDE was
used to construct the basic functionality of the UI.
Implementation
Three events are used in this dialog, OnBeforeSelect, OnBeforeExpand,
and OnButtonClick.
The first events are generated by the
TreeView control. The OnBeforeSelect
and OnBeforeExpand
events both perform similar tasks. Each time the user selects a folder or
clicks to expand a tree node, these events are triggered and upon receiving
these events will scan the selected node identified by the Node parameter in
the TreeViewCancelEventArgs
class.
private void treeView1_BeforeSelect(object sender,
System.Windows.Forms.TreeViewCancelEventArgs e)
{
getSubDirs(e.Node);
textBox1.Text = fixPath(e.Node);
folder = new DirectoryInfo(e.Node.FullPath);
}
private void treeView1_BeforeExpand(object sender,
System.Windows.Forms.TreeViewCancelEventArgs e)
{
getSubDirs(e.Node);
textBox1.Text = fixPath(e.Node);
folder = new DirectoryInfo(e.Node.FullPath);
}
Folder select tree building
Both event handlers call a sub method called getSubDirs()
. This
method will scan for any sub-folders for the given folder. If this
folder has been visited before, no scan is done, since it has already been
entered into the tree control. Note that this does imply that if the
directory structure on the hard drive your examining changes, it will not be
reflected in the dialog until it has been reopened. As the user navigates
to a folder, the TreeView control stores the data needed to construct a full
path to the folder that the user selected. When the dialog is closed with
the Select button, a DirectoryInfo variable "folder" is loaded with the
DirectoryInfo information retrieved when a new instance of this class is
created. The folder information is stored for later access by the
application.
private void getSubDirs( TreeNode parent )
{
DirectoryInfo directory;
try
{
if ( parent.Nodes.Count == 0 )
{
directory = new DirectoryInfo(parent.FullPath);
foreach( DirectoryInfo dir in directory.GetDirectories())
{
TreeNode newNode = new TreeNode(dir.Name);
parent.Nodes.Add(newNode);
}
}
foreach(TreeNode node in parent.Nodes)
{
if (node.Nodes.Count == 0)
{
directory = new DirectoryInfo(node.FullPath);
foreach( DirectoryInfo dir in directory.GetDirectories())
{
TreeNode newNode = new TreeNode(dir.Name);
node.Nodes.Add(newNode);
}
}
}
}
catch( Exception doh )
{
Console.WriteLine(doh.Message);
}
}
Folder select Properties
After closing the folder select dialog with the select button, your application
can retrieve the folder information by calling the public properties fullPath,
name,
and info
. These properties will allow for easy
retrieval of any information stored within the DirectoryInfo
class.
public string name
{
get { return ((folder != null && folder.Exists))? folder.Name : null; }
}
public string fullPath
{
get { return ((folder != null && folder.Exists &&
treeView1.SelectedNode != null))? fixPath(treeView1.SelectedNode) : null; }
}
public DirectoryInfo info
{
get { return ((folder != null && folder.Exists))? folder : null; }
}
Implementation details
Accessing the properties you will notice that we call a private method fixPath()
to correct a problem I discovered with building the tree. The treeView will
only work with paths constructed like the following example. "c:\\Program
Files\Microsoft\...". What this fixPath()
does is strip the
leading "\\" next to the drive letter and replace it with a single "\". This
should be compatible with UNC names as we expect to have a drive letter at the
beginning of the string in order to correct the problem.
private string fixPath( TreeNode node )
{
string sRet = "";
try
{
sRet = node.FullPath;
int index = sRet.IndexOf("\\\\");
if (index > 1 )
{
sRet = node.FullPath.Remove(index, 1);
}
}
catch( Exception doh )
{
Console.WriteLine(doh.Message);
}
return sRet;
}
Dialog invocation code
Here is an example of invoking the folder select dialog.
private void button1_Click(object sender, System.EventArgs e)
{
try
{
FolderSelect dlg = new FolderSelect();
if ( dlg.ShowDialog() == DialogResult.OK)
{
DirectoryInfo info = dlg.info;
textBox1.Text = dlg.fullPath;
string [] strArray = new string[4];
strArray[0] = "Creation Time : "+ info.CreationTime.ToString();
strArray[1] = "Full Name : "+ info.FullName;
strArray[2] = "Last Access Time : "+ info.LastAccessTime.ToString();
strArray[3] = "Last Write Time : "+ info.LastWriteTime.ToString();
textBox3.Lines = strArray;
}
}
catch( Exception err)
{
Console.WriteLine(err.Message);
}
}
Summary
This is just a very simple Windows Form dialog. This should give you a starting
point to build upon. I am not an expert on C# or Forms application at least not
yet. Please do send your comments and suggestions to me. I will try to improve
this application and add some more advanced features.