To read the article online, visit http://www.4GuysFromRolla.com/articles/083006-1.aspx

Using the TreeView Control and a DataList to Create an Online Image Gallery

By Scott Mitchell


The TreeView control, when viewed through a browser.

Introduction


ASP.NET version 2.0 includes a wide array of Web controls not found in previous versions. One such control is the TreeView, which is ideal for displaying hierarchical data. The TreeView control can be bound to a hierarchical data source such as the XmlDataSource or SiteMapDataSource, or can be constructed programmatically. (For an example of using the TreeView to display a site map using the SiteMapDataSource, check out the Examining ASP.NET 2.0's Site Navigation article series.)

One common source of hierarchical data is the web server's file system. In many scenarios, there may be a folder that contains subfolders and files that the user needs to be able to browse. Using the classes in the System.IO namespace, we can programmatically populate the TreeView with the directory structure of our website. Then, when the user clicks a folder, the selected folder's files can be displayed.

In this article we will examine how to create a simple image gallery web page that's a breeze to maintain. The image gallery lacks the bells and whistles found in more complex and feature-rich image galleries, but this one is a cinch to deploy and maintain. We'll be using two Web controls: a TreeView to list the folders and subfolders in which the images reside; and a DataList control that lists each image in the selected folder. Read on to learn more!

This is one of many image-related articles here on 4Guys. Others include: A Robust Image Gallery for ASP.NET; Displaying a List of Scaled Images; and True Image Resizing...

Displaying the TreeView


The application we are creating here has two components:
  • A TreeView control that lists the folders rooted at some specified folder, and
  • A data Web control to list the files in the selected folder. For this article we'll use a DataList, but in other scenarios a GridView, DetailsView, FormView, or Repeater might make more sense.
Let's begin by programmatically creating the TreeView. The ASP.NET 2.0 TreeView's data can be assigned declaratively (through an XmlDataSource or SiteMapDataSource) or programmatically. Since there's no built-in data source control for returning directory information, we'll need to programmatically bind the data to the TreeView. In particular, we need to get information about the root folder and then recurse through the subfolders, adding a TreeNode to the TreeView for each folder encountered.

The .NET Framework contains a plethora of classes for working with the file system; these classes are found in the System.IO namespace. (There are a bevy of FAQs on this namespace at ASPFAQs.com.) One such class is DirectoryInfo, which has methods for returning a given directory's subdirectories (GetDirectories()) as well as a method for returning all of the files in the directory (GetFiles()).

The following code shows how to populate the TreeView PictureTree with the folder hierarchy rooted at the folder specified by the VirtualImageRoot constant. The AddNodeAndDescendents method is the workhorse here, recursing through the folder structure. (For more information on recursion, check out an old article of mine - Recursion, Why It's Cool.)

Private Const VirtualImageRoot = "~/Images/Public/"
Private Sub PopulateTree()
    'Populate the tree based on the subfolders of the specified VirtualImageRoot
    Dim rootFolder As New DirectoryInfo(Server.MapPath(VirtualImageRoot))
    Dim root As TreeNode = AddNodeAndDescendents(rootFolder, Nothing)

    'Add the root to the TreeView
    PictureTree.Nodes.Add(root)
End Sub

Private Function AddNodeAndDescendents(ByVal folder As DirectoryInfo, ByVal parentNode As TreeNode) As TreeNode
    'Add the TreeNode, displaying the folder's name and storing the full path to the folder as the value...
    Dim virtualFolderPath As String
    If parentNode Is Nothing Then
        virtualFolderPath = VirtualImageRoot
    Else
        virtualFolderPath = parentNode.Value & folder.Name & "/"
    End If

    Dim node As New TreeNode(folder.Name, virtualFolderPath)

    'Recurse through this folder's subfolders
    Dim subFolders As DirectoryInfo() = folder.GetDirectories()
    For Each subFolder As DirectoryInfo In subFolders
        Dim child As TreeNode = AddNodeAndDescendents(subFolder, node)
        node.ChildNodes.Add(child)
    Next

    Return node     'Return the new TreeNode
End Function

Each node in the tree has an associated display value and hidden value. The display value is what is shown in the tree; the hidden value is persisted across postbacks and used to associate some extra bit of information with each node. These two values are specified in the TreeNode constructor - Dim node As New TreeNode(text, value). The folder's name is used as the text while the virtual path is used as the value. The virtual path is the path by which a client would request the image - /Images/Public/Picture1.jpg, for example - as compared to the physical path, which would be the actual file path on the web server's file system (such as C:\MySites\ImageGallery\Images\Public\Picture1.jpg. See Using Server.MapPath() for more information on the differences between virtual and physical paths and how Server.MapPath() can be used to translate from a virtual path to a physical one.

Displaying the Files in the Selected Folder


With the file system structure displayed in the TreeView, all that remains is to display the files in the selected folder. To accomplish this, we can add a data Web control to the page and bind its data to the list of files in the currently selected folder. But how can we tell what folder is selected, and how do we know when the user wants to view the files in a different folder?

The TreeView has a SelectedValue property that returns the value of the currently selected node. Recall that we've assigned the folder's virtual path to its corresponding node's value. Given the path to the selected folder, we can get the list of files in that folder by creating a DirectoryInfo object and using its GetFiles() method. This returns an array of FileInfo objects that can be bound to the data Web control (a DataList, for our image gallery).

When a TreeView node is clicked, a postback ensues and the TreeView's SelectedNodeChanged event fires. When this event fires, we want to rebind the data to the data Web control, using the newly selected folder.

These two tasks are accomplished using the following code. The DisplayPicturesInFolder(virtualFolderPath) method gets the files in the specified folder and binds them to DataList PicturesInFolder. The SelectedNodeChanged event handler simply calls DisplayPicturesInFolder(virtualFolderPath), passing in the value of the selected node.

Protected Sub PictureTree_SelectedNodeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureTree.SelectedNodeChanged
    'Refresh the DataList whenever a new node is selected
    DisplayPicturesInFolder(PictureTree.SelectedValue)
End Sub

Private Sub DisplayPicturesInFolder(ByVal virtualFolderPath As String)
    'Security check: make sure folderPath starts with VirtualImageRoot and doesn't include any ".."
    If Not virtualFolderPath.StartsWith(VirtualImageRoot) OrElse virtualFolderPath.IndexOf("..") >= 0 Then
        Throw New ApplicationException("Attempting to view a folder outside of the public image folder!")
    End If

    'Get information about the files in the specified folder
    Dim folder As New DirectoryInfo(Server.MapPath(virtualFolderPath))
    Dim fileList As FileInfo() = folder.GetFiles()

    PicturesInFolder.DataSource = fileList
    PicturesInFolder.DataBind()
End Sub

Note: The first line of code in the DisplayPicturesInFolder(virtualFolderPath) method does a quick security check to make sure that the path being requested is within the folder hierarchy specified by the VirtualImageRoot constant.

The PicturesInFolder DataList contains a single ItemTemplate that displays the name of the image (without the extension) and includes an Image Web control for displaying the picture:

<asp:DataList ID="PicturesInFolder" runat="server" Width="100%" CellPadding="5">
    <ItemTemplate>
        <h3><asp:Label runat="server" ID="FileNameLabel" Text='<%# System.IO.Path.GetFilenameWithoutExtension(Eval("Name")) %>'></asp:Label></h3>
        
        <asp:Image runat="server" ID="Picture" ImageUrl='<%# PictureTree.SelectedValue & Eval("Name").ToString() %>' />
        <br /><br />
    </ItemTemplate>
    <AlternatingItemStyle BackColor="#E0E0E0" />
</asp:DataList>

The end result is a simple image gallery application. The TreeView lists the folders in the file system rooted from a specified starting folder. Clicking on a particular folder in the TreeView displays its images on the right. This image gallery application is a breeze to deploy (as it's just a single ASP.NET page) and to update. To add, edit, or remove images, simply upload, edit, or delete the image files from the web server. The image gallery will immediately reflect the changes!

Happy Programming!

  • By Scott Mitchell


    Attachments


  • Download the image gallery application examined in this article (in ZIP format)
  • Article Information
    Article Title: ASP.NET.Using the TreeView Control and a DataList to Create an Online Image Gallery
    Article Author: Scott Mitchell
    Published Date: August 30, 2006
    Article URL: http://www.4GuysFromRolla.com/articles/083006-1.aspx


    Copyright 2014 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers