Click here to Skip to main content
Click here to Skip to main content

Filesystem TreeView

By , 8 Jul 2005
 

Screenshot

Introduction

There is no file system treeview in .NET 1.1! Therefore I ended up making my own. This is a very basic version of a file system treeview. There are a lot of other methods and or properties that could be added in order to make this a more useful control. However, I have posted this control with the intention that this will save someone some time and aggravation.

Performance is often an issue when dealing with recursion and an extremely large file system. Therefore to overcome this issue I designed this treeview component so it loads on demand. In order to make this happen, I initially only load the root directories and files. Obviously a file can not have any child nodes but a directory on the other hand can have sub-directories and files within it. If a directory has sub-directories and/or files, I add what I describe as a "fake child node". Basically all this means is that I add a child tree node to the "directory node" in order to display the "+" plus sign in front of it. This indicates to the user that they can drill down further to see the sub-directories and files. Here is some example code:

int fileCount = 0;

if( this.TreeView.ShowFiles == true )
    //get a file count
    fileCount = this._directoryInfo.GetFiles().Length;         

//if the directory contains 
//sub-items then add a fake child node to 
//indicate to the user that they can drill down
if( (fileCount + this._directoryInfo.GetDirectories().Length) > 0 )
    new FakeChildNode( this );

The FakeChildNode class is extremely simple. It derives from the TreeNode class and only has a single constructor that adds a child node to an existing node.

public class FakeChildNode : TreeNode
{
    public FakeChildNode( TreeNode parent ) : base()
    {
        parent.Nodes.Add( this );
    }
}

So now that we have the initial directories loaded and virtualized, we can write the code that controls the on-demand loading of the subnodes. In order to do this, I wrote an event handler for the "BeforeExpand" event of the treeview.

void FileSystemTreeView_BeforeExpand(object sender, 
                           TreeViewCancelEventArgs e)
{
    //if node is of type filenode then get out of event
    if( e.Node is FileNode ) return;
        
    DirectoryNode node = (DirectoryNode)e.Node;

    //checks to see if the node has already 
    //been loaded. Basically this just checks to 
    //see if the first child is of type "FakeChildNode"
    if (!node.Loaded)
    {
        //remove the fake child node used for virtualization
        node.Nodes[0].Remove();
        //Load sub-directories and files
        node.LoadDirectory();
        if( this._showFiles == true )
        node.LoadFiles();
    }
}

So now that you understand the basic logistics of this control, here is an example of how you can put it to use:

Using the code

C2C.FileSystem.FileSystemTreeView tree = 
             new C2C.FileSystem.FileSystemTreeView();         
Controls.Add( tree );
tree.Dock = DockStyle.Fill;
//if you want to view only folders 
//you can set the ShowFiles property to true
//tree.ShowFiles = false; 
tree.Load( @"C:\" );

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Michael Ceranski
Software Developer (Senior) Concepts2Code
United States United States
Member
Michael is the co-founder and master consultant for Concepts2Code, a software consulting company based in Buffalo, New York. He's been programming since the early 1990's. His vast programming experience includes VB, Delphi, C#, ASP, ASP.NET, Ruby on Rails, Coldfusion and PHP. Michael also is a Microsoft Certified Application Developer and a Certified Technology Specialist for SQL Server.
 
Visit his blog.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionDisplay System Foldersmemberwynnej198324 Apr '07 - 19:59 
What if I want to load system folders in the treeview such as MyComputer, MyNetwork etc..??D'Oh! | :doh:
QuestionQueston about the selected node full pathmembercervanteskbron17 Apr '07 - 11:00 
Good job first of all, but how come I can't get the full path. I returns the name of the folder only?Confused | :confused:
 
filePath = tv.SelectedNode.FullPath.ToString();
QuestionGreat workmemberBoris Modylevsky22 Oct '06 - 0:04 
Really great work! I compiled it on VS 2005.NET on Framework .NET 2.0 and executed it on Windows 2003 Server SE. It works perfectly, except that some of the icons appear with black background, for example DLL and TXT icons. I found some article describing how to convert some color to transparent color:
http://ewbi.blogs.com/develops/2005/08/sparklines_22.html[^]
 
But it converts ALL the color pixels into transparent ones. Do you have any idea how can we get an icon from the OS with transparent background instead of black?
GeneralRe: Great work - Solution: ColorDepthmemberAssaad Awada28 Apr '08 - 4:25 
Hi Boris,
you just have to set the ColorDepth of the image list.
 
Code:

ImageList imgList = new ImageList();
imgList.ColorDepth = ColorDepth.Depth32Bit;

 
After this the icons will be displayed correctly without the black background.
Hope that this will help you. Smile | :)
 
Best regards
 
Assaad
Questionhow to load the selectedfile int to the browsermemberxall13 Aug '06 - 7:52 
i have made some changes to use the treeview to open the selectedfile in to a axwebbrowser but not only the selected files opens into the browser olso the directory but that is not wat i want.(I use the selectedNode).
i want to load only the selected files (*.html or *.txt not the c:\\ ) not the directory in to the browser .
the next problem that comes up is when i use the open button to load another directory place in to the treeview then i can not use the selectednode or selectedfile for the webbrowser its not recognizing the path .
 
I whant to use webbrowser is to open the *.html documents becouse the richtextbox does not support images like *html.
 
thanx for jour help .D'Oh! | :doh:
 
more people more fun

Questionhow to open a filememberxall30 Jul '06 - 6:21 
hi
 
how can i use the treeview to open files when i dubbelclick ont it
i realy want to use the tree without listview so to doe that i want to use a textbox or richtextbox to open the selected (node)file ..
 
i can't access the textbox from your class becouse iam a beginner.
sorry for my english.
 
please help.

 
more people more fun

AnswerRe: how to open a filememberMichael Ceranski31 Jul '06 - 14:41 
Add this property to the FileNode class
 
public string Filename
{
get{ return _fileInfo.FullName;}
}
 
Create an event handler for the DoubleClick event of the FileSystemTreeView. Then inside the event you can get a handle to the selected node.
 
void tree_DoubleClick(object sender, EventArgs e)
{
if (tree.SelectedNode == null) return;
 
if( tree.SelectedNode.GetType() == typeof(FileNode) ) {
System.Diagnostics.Process.Start(((FileNode)tree.SelectedNode).Filename);
}
}
 
Note: this code only handles nodes that are of type 'FileNode' you should probably add an else statement for the DirectoryNode class.
GeneralSome small additions I made - Return the filename selectedmemberJab_RTS11 Jul '06 - 18:57 
Good work first off Smile | :)
I needed to return the filename/foldername of the node selected so I added the following
 
The start of the class FileSystemTreeView now looks like this

public delegate void MyEventHandler(object sender, MyEventArgs me);

public class FileSystemTreeView : TreeView
{
public event MyEventHandler MyEvent;

private bool _showFiles = true;
private ImageList _imageList = new ImageList();
private Hashtable _systemIcons = new Hashtable();

private string fs = ""; // File/Folder selected

and in the mousedown event I added

this.SelectedNode = node; //select the node under the mouse
fs = node.Text;
if (MyEvent != null)
MyEvent(this, new MyEventArgs(this.fs));

then the class MyEventArgs was added to the namespace C2C.FileSystem

public class MyEventArgs : System.EventArgs
{
public string fs;
public MyEventArgs(string val) : base()
{
this.fs = val;
}
}

 
Finally in the main form load method I added the line & following method
(fns was a simple new label on the form to show the returned filename/folder)

tree.MyEvent += new MyEventHandler(tree_MyEvent);
private void tree_MyEvent(object sender, MyEventArgs me)
{
fns.Text = me.fs;
}

 
Again, thanks...
Jim
 


GeneralRe: Some small additions I made - Return the filename selectedmemberxall30 Jul '06 - 6:23 
does not work for me gives me error on this line
public delegate void MyEventHandler(object sender, MyEventArgs me);
can't find MyEventArgs me ??? is it a Dll or???

 
more people more fun

GeneralFanta FantasticmemberD. Emilio Grimaldo Tuñon29 Jun '06 - 9:51 
Just what I was looking for, well more or less. I was looking for a file system browser and liked the idea that it loads nodes on demand to improve performance.
 
It was however missing something I also needed: to be able to select multiple nodes, not just one as in the standard tree view. Previous to this I had found a project that implemented just that. So I merged those changes into this project, added some extra comments, some design-time properties and now I could use it in solving my problem at hand.
 
Thanks a Lot! Good work!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 8 Jul 2005
Article Copyright 2005 by Michael Ceranski
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid