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

Implementing a common File system browser with a ListView

By , 24 Sep 2003
 

Sample Image - FileSystemListView.jpg

Introduction

Very often, we need to have a control for browsing the user file-system in order to select files or folders in our applications. But Microsoft did not include a control like that with Visual Studio .NET, so I gave it a try and developed a ListView component very similar to the one used in Windows Explorer.

Exceptions

  • Please note that Shell operations are not implemented and are not planned.
  • The "My Documents" icon is not the good one.

Key Features

  • Use the System ImageList for retrieving the icons (pretty fast)
  • Allows to get back to the parent folder (..), so you don't need a companion control or other button for doing that. (AllowParentFolderSelection property)

Usage

Just drag the component onto your form and call the control's Initialize() method in the form Load event.

Conclusions

So this is it. Maybe it will give you a good start for a more complete version.

Credits

  • Thanks to Furty for his works with his TreeView control. It gave me ideas for mine and I used the Shell32 stuff he discovered in coding his control.
  • SystemListView code developed and borrowed from Steve McMahon. Click here for his article.

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

Jonathan Gauthier
Architect CGI
Canada Canada
Member
No Biography provided

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   
GeneralMy vote of 5 PinmemberCpei1 Mar '11 - 19:06 
Thanks i just need this ^^
GeneralAdd-in Code to select a default custom Folder on opening Pinmemberkabamaru13 Dec '10 - 9:35 
This component is simple and efficient, no flourish, just what I needed in my app.
However, Shell32 Intefracing was a REAL Pain ! (Why this choice over Plain'old IO ?)
 
All in all, here is the code I've added in order to open the explorer in a default custom folder :
 
                public void SetDefaultFolder(String folderPath)
                {
                        string[] folders = folderPath.Split('\\');
	      		Shell32.ShellClass shell = new Shell32.ShellClass();
	      		Shell32.Folder folder = shell.NameSpace(Win32API.ShellFolder.MyComputer);
            
                        for (int i = 0; i < folders.Length; i++)
                             folder = getSubFolder(folder, folders[i]);
 
		      	SetListViewItems(folder);
		}
 
		private Shell32.Folder getSubFolder(Shell32.Folder folder, string subfolderName)
		{
			foreach(Shell32.FolderItem folderItem in folder.Items())	
				{
				 if (folderItem.Name.Contains(subfolderName))
					return (Shell32.Folder)folderItem.GetFolder;
				}
                         throw new Exception("Specified Default Folder Not Found");
	        }
 

Usage :
 
           private void Form1_Load(object sender, System.EventArgs e)
		{
                        fileSystemListView1.SetDefaultFolder(@"E:\DATA\LOGS");
			fileSystemListView1.Initialize();
		}

QuestionDoesn't seem to work on VS 2005, have any idea why? Pinmembertrogov11 Dec '07 - 20:46 
Tried to load the project in VS2005 but it's not working.. the icons do not appear on the list view.
AnswerRe: Doesn't seem to work on VS 2005, have any idea why? Pinmembertrogov17 Dec '07 - 5:30 
QuestionUpgrading To .Net 2.0 PinmemberAndreGr12 Nov '06 - 23:45 
Hello,
since I Upgrade my Project (inkl. the control) to .Net 2.0 I didn't get any Icons.
What's wrong after upgrading?
When I debugging the code, I see on:
item.ImageIndex = _smallImageList.IconIndex(folderItem.Path, true);
getting an Index, but the Icon wouldn't show.
 
How can I fix this Problem?
 
Thanks.
AnswerRe: Upgrading To .Net 2.0 PinmemberAndreGr14 Nov '06 - 2:34 
Questionhow to get selected filename Pinmembercskurdal1 Sep '06 - 7:25 
How do I get the filename(s) of the selected files?
 
I'm using VS2005 C#. I can get the directory name (browser.SelectedItem.Path) but I can't find the way to get the selected item filename. The browser variable is a FileBroswer.Browser type that I placed in the GUI.
 
Thanks for any help.... Caleb
GeneralWhy you didn't post the whole project ?! Pinmembermark_md427 Jul '06 - 22:55 
I'd like to debug this project step by step to understand it ,
but the project binding information can not be found so it is treated as not under source control.
 
if there is something to do ,to run this project like normal one please help me.
GeneralRe: Why you didn't post the whole project ?! PinmemberJonathan Gauthier29 Jul '06 - 23:49 
QuestionHidden Folders? PinmemberDaniel Schaffer23 Jan '06 - 4:29 
How can I make this display hidden folders?
AnswerRe: Hidden Folders? PinmemberJos Branders31 Oct '09 - 6:52 
GeneralAdd sorting capability PinmemberDemonFox5 Sep '05 - 0:28 
If you simply change the "Sorting" property to be "Ascending" or "Descending", you will find all the system icons are lost when you run the program.
 
Replace the file FileSystemListView.cs with this one:
 
http://www.stanford.edu/~yuanyuan/public/FileSystemListView.cs
 
and compile the control again. You should get proper sorting now.
 
The new source also contains fix for displaying pdf & zip files.
 
Do a windiff to see where the actual changes are.
GeneralRe: Add sorting capability PinmemberMark Johnson24 Aug '07 - 20:00 
GeneralProblem finding bug.. Pinmemberdermoultam16 Aug '05 - 19:55 
I think there is a problem with the Shell32.ShellSpecialFolderConstants in the Win32API.cs code. I get the following exception when I compile the FileSystemListViewDemo project code, run it, and double click on first "My Computer", "Administrator's Documents" (I log in as Administrator, this is a system shortcut for My Documents), then double click on any folder in this view (besides the parent .. folder).
It occurs on line 397 of FileSystemListView.cs.
 
************** Exception Text **************
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: '-1' is not a valid value for 'displayIndex'.
at System.Windows.Forms.ListViewItemCollection.get_Item(Int32 displayIndex)
at LivingObjects.Windows.Forms.FileSystemListView.AddParentItem(Folder folder)
at LivingObjects.Windows.Forms.FileSystemListView.SetListViewItems(Folder folder)
at LivingObjects.Windows.Forms.FileSystemListView.FileSystemListView_DoubleClick(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnDoubleClick(EventArgs e)
at System.Windows.Forms.ListView.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 

 
My assembly info:
************** Loaded Assemblies **************
mscorlib
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll
----------------------------------------
FileSystemListViewDemo
Assembly Version: 1.0.2054.28849
Win32 Version: 1.0.2054.28849
CodeBase: file:///C:/Programming/VS/Danny/FileSystemListViewDemo/bin/Release/FileSystemListViewDemo.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.windows.forms/1.0.5000.0__b77a5c561934e089/system.windows.forms.dll
----------------------------------------
System
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll
----------------------------------------
System.Drawing
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll
----------------------------------------
LivingObjects
Assembly Version: 0.9.2054.28849
Win32 Version: 0.9.2054.28849
CodeBase: file:///C:/Programming/VS/Danny/FileSystemListViewDemo/bin/Release/LivingObjects.DLL
----------------------------------------
Interop.Shell32
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///C:/Programming/VS/Danny/FileSystemListViewDemo/bin/Release/Interop.Shell32.DLL
----------------------------------------
CustomMarshalers
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/custommarshalers/1.0.5000.0__b03f5f7f11d50a3a/custommarshalers.dll
----------------------------------------

Generaladd context (right-click) menu with delete file, rename file, create directory, delete directory PinsussKenneth Scott30 Jun '05 - 17:20 
just in case anybody's interested, here's some code you can use in your application if you add a right-click context menu to the fileSystemListView1 control:
 
they work really well in conjunction with Chris Hambleton's DisplayFolder routine (to refresh the view):
 
private void menuLocalRename_Click(object sender, System.EventArgs e)
{
try
{
if ( fileSystemListView1.SelectedItems.Count > 0 )
{
if ( fileSystemListView1.SelectedItems[0].GetType().Name.ToString() == "FileListViewItem" )
{
FileListViewItem file = fileSystemListView1.SelectedFileItems[0];
// use nfo to get full filename
FileInfo nfo = file.FileInfo;
 
//get clean directory name of file to be deleted
FileInfo fi = new FileInfo(nfo.FullName.ToString());
 
InputBoxResult newFileName = InputBox.Show("Rename File To ","File Rename",fi.Name,1499,1065);
if ( newFileName.ReturnCode == DialogResult.OK )
{
if ( File.Exists(fi.DirectoryName + "\\" + newFileName.Text) == false )
{
File.Move(nfo.FullName.ToString(), fi.DirectoryName + "\\" + newFileName.Text);

fileSystemListView1.DisplayFolder(fi.DirectoryName);
}
else
{
MessageBox.Show("Rename *To* Filename Already Exists");
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
 
private void menuLocalDelete_Click(object sender, System.EventArgs e)
{
try
{
if ( fileSystemListView1.SelectedItems.Count > 0 )
{
if ( fileSystemListView1.SelectedItems[0].GetType().Name.ToString() == "FileListViewItem" )
{
if (MessageBox.Show ("Are you sure you want to delete this file? ", "Delete Local File",
MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
FileListViewItem file = fileSystemListView1.SelectedFileItems[0];
FileInfo nfo = file.FileInfo;
 
//get clean directory name of file to be deleted
FileInfo fi = new FileInfo(nfo.FullName.ToString());

//now delete it
if ( File.Exists(nfo.FullName.ToString()) == true )
{
File.Delete(nfo.FullName.ToString());

}
else
{
MessageBox.Show("File Does Not Exist.");
}
//now refresh the explorer listing of that folder
fileSystemListView1.DisplayFolder(fi.DirectoryName);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
 
private void menuLocalCreateDir_Click(object sender, System.EventArgs e)
{
try
{
InputBoxResult dir = InputBox.Show("Directory Name ","Create Directory","",1499,1065);
if ( dir.ReturnCode == DialogResult.OK )
{
FolderListViewItem folder = checked ((FolderListViewItem) fileSystemListView1.Items[0]);
DirectoryInfo nfo = folder.DirectoryInfo;
 
if (Directory.Exists(nfo.FullName.ToString() + "\\" + dir.Text) == false )
{
Directory.CreateDirectory(nfo.FullName.ToString() + "\\" + dir.Text);
//now refresh the explorer listing of that folder
fileSystemListView1.DisplayFolder(nfo.FullName.ToString());
}
else
{
MessageBox.Show("Directory Already Exists");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
 
}
 
private void menuLocalDeleteDir_Click(object sender, System.EventArgs e)
{
try
{
if ( fileSystemListView1.SelectedItems.Count > 0 )
{
if ( fileSystemListView1.SelectedItems[0].GetType().Name.ToString() == "FolderListViewItem" )
{
FolderListViewItem folder = checked ((FolderListViewItem) fileSystemListView1.SelectedItems[0]);
//get folder info for selected folder
DirectoryInfo nfo = folder.DirectoryInfo;
 
if (MessageBox.Show ("Are you sure you want to delete this directory? ", "Delete Local File",
MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
if (Directory.Exists(nfo.FullName.ToString()) == true )
{
//delete the directory
Directory.Delete(nfo.FullName.ToString(), true);

//refresh current directory
fileSystemListView1.DisplayFolder(nfo.Parent.FullName.ToString());
}
else
{
MessageBox.Show("Directory Does Not Exist");
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

}
 
hope it helps-
Kenneth
GeneralAdd . (currentfolder) to control and also add missing files PinsussKenneth Scott30 Jun '05 - 17:05 
I was always forgetting which folder I was in since the view only shows the ..(parentfolder) at the top - so I cloned that code and produced this routine to add .(currentfolder)
 
///
/// Add a ListViewItem in the ListView corresponding to the Current Folder
/// so you can easily tell where you are.
///

///
private void AddCurrentItem(Shell32.Folder folder)
{
Shell32.FolderItems folderItems;
string currentName = "";
 
//The specified folder has a Parent
if(folder.ParentFolder != null)
{
//We need to find a FolderItem object corresponding
//to the Parent. There is no known straight way of doing
//this excepting looping though all the Folder items
//the Parent contains until we find the corresponding
//instance.
folderItems = folder.ParentFolder.Items();

foreach(Shell32.FolderItem folderItem in folderItems)
{
//We find it !
if(folderItem.Name == folder.Title)
{
AddItem(folderItem);
currentName = folderItem.Name;

break;
}
}
}
else //The parent is the desktop
{
//Get a reference on the Desktop Folder
Shell32.Shell shell32 = new Shell32.ShellClass();
Shell32.Folder desktopFolder = shell32.NameSpace(Win32API.ShellFolder.DesktopDirectory);

folderItems = desktopFolder.ParentFolder.Items();
 
//We need a FolderItem instance corresponding to the Desktop
//but we cannot obtain it directly, so loop though it's Parent
//until we get it.
foreach(Shell32.FolderItem folderItem in folderItems)
{
if(folderItem.Name == desktopFolder.Title)
{
AddItem(folderItem);
currentName = folderItem.Name;

break;
}
}
}
 
//Overwrite the default appearance of the Added ListViewItem
((ExplorerListViewItem)(this.Items[Items.Count - 1])).SubItemName = ". (" + currentName + ")";
((ExplorerListViewItem)(this.Items[Items.Count - 1])).SubItemTypeName = "Current Folder";
((ExplorerListViewItem)(this.Items[Items.Count - 1])).SubItemModifiedDate = "";
((ExplorerListViewItem)(this.Items[Items.Count - 1])).SubItemSize = "";
 
}
 
it looks like crap pasted in here, but you should be able to just copy and paste it into the code.
just call it from the SetListViewItems routine, just before the call to AddParentItem(folder).. so it would look like this:
 
AddCurrentItem(folder); <-- new
if(AllowParentFolderSelection) <--existing
AddParentItem(folder); <--existing
 
also.. speaking of the SetListViewItems routine.. i changed the following code to display the missing files people were talking about (zip's, pdf's, etc):
 
change from:
if((folderItem.IsFileSystem || folderItem.IsFolder) && !folderItem.IsBrowsable && folderItem.Name != "Control Panel")
 
change to:
if ( folderItem.Name != "My Network Places" && folderItem.Name != "Control Panel" )
 
(i'm skipping My Network Places because it's got issues..)
but be warned though that if you've added code to launch files by double-clicking, not all of these new ones will open.. you may get errors, bad paths, etc.
also, for some reason some zips will let you browse them and some will crash.. it seems similar to the icon issue with "my network places".. but i can't find a rhyme or reason - if anybody knows, please let me know-
 
hope it helps-
Kenneth
GeneralRe: Add . (currentfolder) to control and also add missing files PinsussKenneth Scott2 Jul '05 - 13:17 
GeneralException during browsing of &quot;My Network Places&quot; Pinmemberom31 May '05 - 22:26 
---------------------------
Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue
---------------------------
Failed to get icon index
 

 

 
at SystemImageList.IconIndex(String fileName, Boolean forceLoadFromDisk, ShellIconStateConstants iconState) c:\Projects\JagExpress\ClientApp\samples\FileSystemListView_src\LivingObjects\Windows\Forms\SystemImageList.cs(775)
 
at SystemImageList.IconIndex(String fileName, Boolean forceLoadFromDisk) c:\Projects\JagExpress\ClientApp\samples\FileSystemListView_src\LivingObjects\Windows\Forms\SystemImageList.cs(722)
 
at FileSystemListView.AddItem(FolderItem folderItem) c:\projects\jagexpress\clientapp\samples\filesystemlistview_src\livingobjects\windows\forms\filesystemlistview.cs(420)
 
at FileSystemListView.SetListViewItems(Folder folder) c:\projects\jagexpress\clientapp\samples\filesystemlistview_src\livingobjects\windows\forms\filesystemlistview.cs(322)
 
at FileSystemListView.FileSystemListView_DoubleClick(Object sender, EventArgs e) c:\projects\jagexpress\clientapp\samples\filesystemlistview_src\livingobjects\windows\forms\filesystemlistview.cs(277)
 
at Control.OnDoubleClick(EventArgs e)
 
at ListView.WndProc(Message& m)
 
at ControlNativeWindow.OnMessage(Message& m)
 
at ControlNativeWindow.WndProc(Message& m)
 
at NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 
at UnsafeNativeMethods.DispatchMessageW(MSG& msg)
 
at ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
 
at ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
 
at ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
 
at Application.Run(Form mainForm)
 
at Form1.Main() c:\projects\jagexpress\clientapp\samples\filesystemlistview_src\filesystemlistviewdemo\form1.cs(92)
 

---------------------------
Abort Retry Ignore
---------------------------

GeneralHELP - Don't show ZIP and PDF files ! PinmemberLe_MuLoT8 Apr '05 - 6:43 
In the same directory I putted 3 files, a DOC, a ZIP and a PDF but there's only the DOC that appear...
GeneralRe: HELP - Don't show ZIP and PDF files ! PinmemberLe_MuLoT15 Sep '05 - 10:38 
GeneralExecuting Selected Files PinmemberLe_MuLoT8 Apr '05 - 3:36 
Hi,
 
I don't know if the control already give a function like the one I'll give now, but if it's that case, just tell me. Poke tongue | ;-P
 

//Adding this code in FileSystemListView
public void RunSelectedFileItems()
{
	if (this.SelectedFileCount > 0)
	{
		System.Diagnostics.Process proc;
		foreach(LivingObjects.Windows.Forms.FileListViewItem file in this.SelectedFileItems)
		{
			proc = new System.Diagnostics.Process();
			proc.StartInfo.FileName = file.FileInfo.DirectoryName + "\\" + file.Text;
			proc.Start();
		}
	}
}
 
//Adding this code at the Item Activate event of the fileSystemListView
private void fileSystemListView1_ItemActivate(object sender, System.EventArgs e)
{
	try
	{
		this.fileSystemListView1.RunSelectedFileItems();
	}
	catch(System.Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}

GeneralAny one implemented this in vb.net PinsussVanjari22 Sep '04 - 3:26 
Any one implmeted this in vb.net I mean written the entire code in vb.net?
If so can you post it thnaks

GeneralRe: Any one implemented this in vb.net PinmembereelisMX23 Sep '04 - 4:40 
Generalvisual studio .net 2005 beta PinsussAnonymous11 Sep '04 - 16:16 
If I build the project with VS.NET 2005 Beta, the icons don't show up when I run the sample program. Anyone know how to fix this?

GeneralRe: visual studio .net 2005 beta PinmemberWilsonProgramming8 Nov '04 - 13:41 

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 25 Sep 2003
Article Copyright 2003 by Jonathan Gauthier
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid