Building a Vista Style Folder Browser with ASP.NET 3.5 and a Custom Hierarchical DataSource Control
A while back, I wrote a post describing how to create a folder browser with ASP.NET 2.0 using the TreeView, UpdatePanel, GridView (customized to always display header row) and a modified version of the FileSystemDataSource as described on MSDN. I have used this widget on a few different projects and I generally like how it works (you can view the demo here).
One thing my original implementation is clearly lacking is a professional look and feel. So I recently had the opportunity to upgrade it to .Net 3.5 and in the process I decided it was time to overhaul the style. Using the Vista folder explorer as my template, I made the following changes to the original sample ...
- Replaced the plus/minus icons with dark and light arrows
- Added soft blue rounded corners to the explorers container
- Added modified date column to the right hand pane
- Added a footer the displays the name and modified date of the currently selected folder
I have hit most of the implementation high points below - so read on if you are interested.
Live Demo (IE6, IE7, FF and Opera) | Download (.Net 3.5)
The FileSystemDataSource
The MSDN documentation for the HierarchicalDataSourceControl provides a sample implementation for binding to files and folders. I took this sample implementation and made a handful of minor modifications, including specifying if you would like folders and files retrieved or just folders. Here is a sample configuration that is used for the above screen shot.
If you do not want the root folder to be displayed, just set the IncludeRoot attribute to false and the folders will render as follows (notice there is no top level root node anymore). In my original post I received quite a few questions about how this could be done so I figured I would add it in with this example.
Configuring the Folder TreeView
After setting up the datasource, I went ahead and created the markup for the TreeView that displays that folders. Most of the markup is for controlling the styling. I have added CssClasses for the tree's container as well as custom classes for nodes and selected nodes. I have also added an event handler for the SelectedNodeChanged event so I can update the right hand pane with the selected folders contents as the user selects different folders from the left hand pane.
Folder Contents ListView
I am using ASP.NET 3.5's new ListView control to handle rendering the right hand pane of the folder browser. This is just a standard HTML table with 3 columns: Name, Date modified and Size. I also added an EmptyDataTemplate that renders the 'This folder is empty' where there are no items in the selected folder. When the user selects a folder from the left hand pane, I programmatically fetch all of the FileSystemInfo objects for the selected folder and assign this collection to the ListView's DataSource property.
I am also attaching to the ListView's ItemDataBound and ItemCommand event handlers. From the ItemDataBound handler, I need to check if the FileSystemInfo object being bound to is a FileInfo or DirectoryInfo object. If it is a DirectoryInfo, I need to assign the folder icon. If it is a file I need to calculate the size of the file as well as set the pdf file icon. For the case where the databound item is a FileInfo object I am also registering the image and link buttons as full postback controls so the file can be properly written to the Response stream when the user clicks on either of the buttons. Failing to do this will cause that dreaded PageRequestManagerParserErrorException - the UpdatePanel doesn't like the Response object to be modified directly.
Note: If you have a terrible memory like me, make sure you bookmark the ListViewDataItem class. It shows an example of how to access the databound item from the ItemDataBound event handler. If the ItemType of the ListViewItem is a DataItem, you can cast the ListViewItem as a ListViewDataItem and use the DataItem property to get at the databound item (FileSystemInfo's for my example). From using the GridView, I got used to getting right at the data item from the DataBound event handler - with the ListView you have to do just a little bit more work.
Folder Detail Footer
If you look back at the demo page or screen shot below, you will also notice that I included some additional context information for the selected folder in the browsers footer. This is just a DetailsView that I bind as the user changes the selected folder.
The IE6 Doubled Float-Margin Bug
I chose to use a floating DIV for the left pane portion of the control. In doing so I bumped into an IE6 bug that I am sure most of you are familiar with - in certain situations IE6 doubles the margins of containers that are floated. Here is a good description of the problem and a solution. Another browser specific quirk to try to remember when troubleshooting ...
ToDo
I like my new Vista styled explorer - much better looking than the original incarnation. But I didn't get to everything I wanted. Here are a few of the remaining items that I still need to add ...
- Add sorting to the column headers
- Add a progress indicator while the folder listings are being retrieved
- Add support for scrolling the right hand pane. Ideally, freeze the column headers and save a little room to the right of the pane for the scroll bar.
That's it. Enjoy!
Comments
Very nice. This could be a great start to a web based file manager application for end users to upload/rename/move files used in a CMS. Thanks.
Hi Matt!
Great work and your blog is so fantastic because you have so many good examples
Wow! Really cool redesign of the folder explorer example. I think an Ajax loading panel/progress indicator would fit in perfectly (like a rotating arrow)and add that polish to things. Some other user-friendly additions could be hover effects on the items as well as a context menu for editing,deleting nodes. Thanks for yet another great example Matt!
Hi Matt,
Very good Article,
and for sure as Steve said, I am going to use in my new CRM system.
Your update post back is something like 6,463 bytes. Does this get bigger if the nav tree gets bigger?
@Nick: how those numbers come from "6,463 bytes"?
how did you calculate?
thanks
Its cool.
Thenk you
Hello.
It is great piece of code. I have downloaded it and tested it but I have one issue I would like to ask you about.
If I point path to the folder that is outside the project forlders, like for instance \webserverfolders
then it returns an error..
Am I doing something wrong?
What I am trying to do is that users can read files in the folders that are inside our nettwork.
Very cool. A great thank from a Vietnamese friend :)
I came looking for rounded corner suggestions for table. Did not find, but will download source.
Excellent site ! lots of great examples.
Thanx, Tom
Nice demo. Need a way to utilize AJAX to have memu options when row or branch is highlighted.
I tried to modify it with two buttons, one for open(read only), and one for modify. My purpose is use it to build a web based WebDAV resource page for special user usage.
The problem is client-side JavaScript and server-side ASP variable/function is stick me for a few days.
Any good suggestion?
this looks excellent!! Is there anyway , so that i could read a folder of client machine!!
Matt - very nice. But what I need is a folder picker. I need to be able to browse to a folder, double click on it, and return the path and folder name to the program.
Any chance your control could do that for me? Or, do you know of a folder picker?
Thanks in advance for the help
Greg
Hi there, I have downloaded this and really like its design. Although I have a little problem with it. When I have very large files (e.g. 500 MB files) in a folder and click them Firefox just endlessly tries to load it while IE starts the download after about 2-3 minutes. On the webserver the IIS Worker process consumes almost 3 GBs of Ram when clicking this file. Any idea what is wrong there?
Best Regards
Chris
I like this alot and have been using it for a personal project. There is a couple of things i wanted to ask. If you have a folder listed on the right hand site and click on it, it wont update the folder details in the footer. Also is there a way to not show the folders on the right hand side. Is there any way to hide file extensions or the time?
Thanks
very nice Folder Browser. I add delete function (follow ImageButton process and CommandName= DelFile and Delete code.). how to do use ajax get realtime data.
thank you.
This is a Great tool!! Thanks for sharing!