Click here to Skip to main content
15,922,894 members
Articles / Programming Languages / C#
Article

An "Explorer-Style" TreeView Control

Rate me:
Please Sign up or sign in to vote.
4.62/5 (39 votes)
21 Feb 20062 min read 330.9K   15.8K   153   84
An article describing how to create an Explorer-style treeview with system icons.

ExplorerTreeView Demo

Introduction

This is a simple TreeView derived control that mimics the Windows Explorer interface. It provides no added functionality aside from the standard TreeView control methods, properties, and events, however it does provide a ShellItem class, which can be used to extend this basic example for your own needs, and it is also a good starting point for those wanting to get to grips with the system image list and Shell32 programming.

Background

Originally, I started researching this topic as I wanted to develop an FTP client in C# that would implement a local system explorer similar to that of the Windows Explorer, but it soon became apparent that it was not going to be an easy undertaking. Thanks to CodeProject and other code repositories, I came across some good examples of how to achieve what I wanted, however the best examples were written in VB.NET or Delphi, so I decided to write a simple C# control based on what I'd found.

Parts of the code are based on other CodeProject tutorials and code samples found elsewhere on the Internet. All of the code was written by myself but some of the concepts were "borrowed".

Helpful Hints

For each node in the TreeView, an associated ShellItem object is created and stored in the node's "Tag" property. The ShellItem object allows you to retrieve information for the shell folder represented by the node, such as whether the folder has any sub-folders. For example, in the TreeView's "OnBeforeCollapse" event, we can obtain the ShellItem object to perform a simple test...

C#
ShellItem shNodeItem = (ShellItem)e.Node.Tag;
if (shNodeItem.HasSubFolder)
    // Do something...

We can also get the folder's IShellFolder interface from the ShellItem object using the ShellFolder property. Using this interface, we can do all sorts of nifty stuff, such as implementing shell context menus:

C#
// Get the ShellItem for this node.
ShellItem shNodeItem = (ShellItem)e.Node.Tag;

// Create an array of PIDL's for obtaining
// the IContextMenu interface pointer.
IntPtr[] arrPidls = new IntPtr[0]; 
arrPidls[0] = shNodeItem.PIDL;

// Request the interface pointer.
uint uRetVal = 
  shNodeItem.ShellFolder.GetUIObjectOf(IntPtr.Zero, 
  1, arrPidls, ref IID_IContextMenu, 
  IntPtr.Zero, out pCtx);
if (uRetVal != 0)
    Marshal.ThrowExceptionForHR((int)uRetVal);

...

Marshal.ReleaseComObject(pCtx);

History

None yet.

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


Written By
Software Developer
United Kingdom United Kingdom
Software Engineering Undergraduate

Comments and Discussions

 
GeneralRe: Looks really nice, but does not have much functionality yet Pin
MrPJ26-Feb-06 23:28
MrPJ26-Feb-06 23:28 
GeneralASP.NET 2.0 Pin
tkdmaster17-Feb-06 17:15
tkdmaster17-Feb-06 17:15 
GeneralRe: ASP.NET 2.0 Pin
MrPJ18-Feb-06 0:46
MrPJ18-Feb-06 0:46 
GeneralRe: ASP.NET 2.0 Pin
chrisv21-Feb-06 15:57
chrisv21-Feb-06 15:57 
GeneralExcellent! Pin
Mark Belles17-Feb-06 8:40
Mark Belles17-Feb-06 8:40 
GeneralRe: Excellent! Pin
MrPJ17-Feb-06 8:57
MrPJ17-Feb-06 8:57 
GeneralRe: Excellent! Pin
Mark Belles17-Feb-06 9:48
Mark Belles17-Feb-06 9:48 
GeneralRe: Excellent! Pin
MrPJ17-Feb-06 11:45
MrPJ17-Feb-06 11:45 
Mark (Code6) Belles wrote:
The context menu code is also very interesting. I did one way back, but it was painful lol. I never focused real hard other than trying to understand how it worked.


Yes it's pretty much a case of copying the SetTVImageList method and changing the TVM_* constants to LVM_*. Listing the files is also quite simple. It just requires using SHCONTF_NONFOLDERS rather than SHCONTF_FOLDERS.

The main problem I'm experiencing is that it is just too slow for my liking. If you open up the system32 folder or the ServicePackFiles\i386 folder it takes about 2-3 seconds to display the files even when using a virtual ListView. The cause of the problem is having to retrieve and display the icon for each file as well as obtaining the file size and last modified date. I'm going to try experimenting with the .NET file related classes as well as IFolderItem and see which works best. Something I've just thought of while writing this reply is possibly using a HashTable to keep track of the icons used for particular file types so that it doesn't retrieve the icon index for every file and just looks it up in the HashTable. I'm not sure how well that will work but it's worth a try.

I'm trying to model the system explorer on the one used by AbsoluteFTP (vandyke.com). I assume theirs is C++ but it performs really well. There is hardly any delay when viewing large folders.

Mark (Code6) Belles wrote:
I was noticing that the ShellImageList class would only need a few mods to get the right constants to set the ListView's image list, and then you'd be off to the races.


The example code I posted in the other thread will display the shell context menu correctly for each node but I'm still working on how to process mouse clicking and performing the correct action. I can't quite see how it works. I've seen lots of C++ examples that use TrackPopupMenu to determine which menu item was clicked so I'm not sure if I need to do that or whether I need to use WndProc or something else. Blah.

Regards,
Paul Wilson
GeneralRe: Excellent! Pin
Paul Conrad25-Feb-06 10:39
professionalPaul Conrad25-Feb-06 10:39 
QuestionContext Menu Pin
Steve Hansen17-Feb-06 7:13
Steve Hansen17-Feb-06 7:13 
AnswerRe: Context Menu Pin
MrPJ17-Feb-06 8:18
MrPJ17-Feb-06 8:18 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.