The last example in this chapter combines the TreeView and ListView controls. It’s a fairly advanced example, but I included it here for the most ambitious readers. It can also be used as the starting point for many custom applications, so give it a try. You can always come back to this project after you’ve mastered other aspects of the Framework, such as the FileIO namespace.
The CustomExplorer project, shown in Figure 4.32, displays a structured list of folders in the left pane, and a list of files in the selected folder in the right pane. The left pane is populated when the application starts, and it might take a while. On my Pentium system, it takes nearly 30 seconds to populate the TreeView control with the structure of the Windows folder (which includes FallBack folders and three versions of the Framework; more than 50,000 files in 1,700 folders in all). You can expand any folder in this pane and view its subfolders. To view the files in a folder, click the folder name, and the right pane will be populated with the names of the selected folder’s files, along with other data, such as the file size, date of creation, and date of last modification. You haven’t seen the classes for accessing folders and files yet, but you shouldn’t have a problem following the code. If you have to, you can review the members of the IO namespace in Chapter 15, in which I discuss in detail the same project’s code.
This section’s project is not limited to displaying folders and files; you can populate the two controls with data from several sources. For example, you can display customers in the left pane (and organize them by city or state) and display their related data, such as invoices and payments, in the right pane. Or you can populate the left pane with product names, and the right pane with the respective sales. In general, you can use the project as an interface for many types of applications. You can even use it as a custom Explorer to add features that are specific to your applications.
Figure 4.32 – The CustomExplorer project demonstrates how to combine a TreeView and a ListView control on the same form.
The TreeView control on the left pane is populated from within the Form’s Load event handler subroutine with the subfolders of the C:\Program Files folder:
Dim Nd As New TreeNode() Nd = TreeView1.Nodes.Add("C:\Program Files") ScanFolder("c:\Program Files", ND)Code language: VB.NET (vbnet)
The first argument is the name of the folder to be scanned, and the second argument is the root node, under which the entire tree of the specified folder will appear. To populate the control with the files of another folder or drive, change the name of the path accordingly. The code is short, and all the work is done by the ScanFolder() subroutine. The ScanFolder() subroutine, which is a short recursive procedure that scans all the folders under a specific folder, is shown in Listing 4.51.
Listing 4.51: The ScanFolder() Subroutine
Sub ScanFolder(ByVal folderSpec As String, _ ByRef currentNode As TreeNode) Dim thisFolder As FileIO.Folder Dim allFolders As FileIO.FolderCollection allFolders = My.Computer.FileSystem. _ GetFolder(folderSpec).FindSubFolders("*.*") For Each thisFolder In allFolders Dim Nd As TreeNode Nd = New TreeNode(thisFolder.FolderName) currentNode.Nodes.Add(Nd) folderSpec = thisFolder.FolderPath ScanFolder(folderSpec, Nd) Me.Text = "Scanning " & folderSpec Me.Refresh() Next End SubCode language: VB.NET (vbnet)
The variable FolderSpec represents the current folder (the one passed to the ScanFolder() subroutine as an argument). The code creates the allFolders collection, which contains all the subfolders of the current folder. Then it scans every folder in this collection and adds its name to the TreeView control. After adding a folder’s name to the TreeView control, the procedure must scan the subfolders of the current folder. It does so by calling itself and passing another folder’s name as an argument.
Notice that the ScanFolder()subroutine doesn’t simply scan a folder. It also adds a node to the TreeView control for each new folder it runs into. That’s why it accepts two arguments: the name of the current folder and the node that represents this folder on the control. All folders are placed under their parent folder, and the structure of the tree represents the structure of your hard disk (or the section of the hard disk you’re mapping on the TreeView control). All this is done with a small recursive subroutine: the ScanFolder() subroutine.
Viewing a Folder’s Files
To view the files of a folder, click the folder’s name in the TreeView control. As explained earlier, the action of the selection of a new node is detected with the AfterSelect event. The code in this event handler, shown in Listing 4.52, displays the selected folder’s files on the ListView control.
Listing 4.52: Displaying a Folder’s Files
Private Sub TreeView1 AfterSelect(...) _ Handles TreeView1.AfterSelect Dim Nd As TreeNode Dim pathName As String Nd = TreeView1.SelectedNode pathName = Nd.FullPath ShowFiles(pathName) End SubCode language: VB.NET (vbnet)
The ShowFiles() subroutine actually displays the filenames, and some of their properties, in the specified folder on the ListView control. Its code is shown in Listing 4.53.
Listing 4.53: The ShowFiles() Subroutine
Sub ShowFiles(ByVal selFolder As String) ListView1.Items.Clear() Dim files As FileIO.FileCollection Dim file As FileIO.File files = My.Computer.FileSystem.GetFolder(selFolder).FindFiles("*.*") Dim TotalSize As Long For Each file In files Dim LItem As New ListViewItem LItem.Text = file.FileName LItem.SubItems.Add(file.Size.ToString("#,###")) LItem.SubItems.Add( _ FormatDateTime(file.CreatedTime, _ DateFormat.ShortDate)) Item.SubItems.Add( _ FormatDateTime(file.AccessedTime, _ DateFormat.ShortDate)) ListView1.Items.Add(LItem) TotalSize += file.Size Next Me.Text = Me.Text & " [" & TotalSize.ToString("#,###") & " bytes]" End SubCode language: VB.NET (vbnet)
The ShowFiles()subroutine creates a ListItem for each file. The item’s caption is the file’s name, the first subitem is the file’s length, and the other two subitems are the file’s creation and last access times. You can add more subitems, if needed, in your application. The ListView control in this example uses the Details view to display the items. As mentioned earlier, the ListView control will not display any items unless you specify the proper columns through the Columns collection. The columns, along with their widths and captions, were set at design time through the ColumnHeader Collection Editor.
The discussion of the CustomExplorer sample project concludes the presentation of the TreeView and ListView controls. However, there are a few more interesting topics you might like to read about, which weren’t included in this chapter. Like all Windows controls, the ListView control doesn’t provide a Print method, which I think is essential for any application that displays data on this control. In Chapter, “Printing with Visual Basic 2008,” you will find the code for printing the items of the ListView control. The printout we’ll generate will have columns, just like the control, but it will display long cells (items or subitems with long captions) in multiple text lines. Finally, in Chapter “Serialization and XML in Visual Basic 2008” you’ll learn how to save the nodes of a TreeView control to a disk file between sessions by using a technique known as serialization. In that chapter, you’ll find the code behind the Load Nodes and Save Nodes buttons of the Globe project and a thorough explanation of their function.