1. Home
  2. Computing & Technology
  3. Visual Basic
Creating the Directory List Control
Beyond the Book: User Interfaces in VB .NET
 Know Even More?
Tell Us About It!
 
 Related Resources
• About.com Review
  User Interfaces in VB .NET
• User Control Components in VB .NET

There is some excellent code available in Matthew MacDonald's book, User Interfaces in VB .NET (reviewed HERE by About Visual Basic) that lets you extend the TreeView control in VB .NET into a Directory Viewer control using inheritance. As MacDonald writes in his book:

.NET does not include any type of native directory control so this TreeView is genuinely useful.

MacDonald's code starts on page 276 and works very well. But if you're like me, you might run into a few rough spots when you actually try out the code in your own program. We'll go over what they are.

MacDonald also leaves a tease at the end, "Another option is to ... modify the Designer code ..." but the demonstration about how to do that is a bit thin. We'll see how that works too because there is a surprise in the result.

The Visual Studio GUI incudes direct support for building User Controls. About Visual Basic covered this (including a tip about doing it with the much less expensive "Learning Edition" that we recommend) in this recent article. In many ways, basing a control on an existing control by inheriting it in a class is a better way to go. You get all the functionality of the existing control plus the modifications that you add. The existing TreeView control provides nearly all of the capability that you need for a great DirectoryTree control. MacDonald shows us the rest as follows:

Imports System.IO

Public Class DirectoryTree
    Inherits TreeView
    Event DirectorySelected( _
        ByVal sender As Object, _
        ByVal e As DirectorySelectedEventArgs)
    Private _Drive As Char
    Public Property Drive() As Char
        Get
            Return _Drive
        End Get
        Set(ByVal Value As Char)
            _Drive = Value
            RefreshDisplay()
        End Set
    End Property
    Public Sub RefreshDisplay()
        Me.Nodes.Clear()
        Dim RootNode As New TreeNode(_Drive & ":\")
        Me.Nodes.Add(RootNode)
        Fill(RootNode)
        Me.Nodes(0).Expand()
    End Sub
    Private Sub Fill(ByVal DirNode As TreeNode)
        Dim Dir As New DirectoryInfo(DirNode.FullPath)
        Dim DirItem As DirectoryInfo
        For Each DirItem In Dir.GetDirectories
            Dim NewNode As New TreeNode(DirItem.Name)
            DirNode.Nodes.Add(NewNode)
            NewNode.Nodes.Add("*")
        Next
    End Sub
    Protected Overrides Sub _
        OnBeforeExpand(ByVal e As TreeViewCancelEventArgs)
        MyBase.OnBeforeExpand(e)
        If e.Node.Nodes(0).Text = "*" Then
            e.Node.Nodes.Clear()
            Fill(e.Node)
        End If
    End Sub
    Protected Overrides Sub _
        OnAfterSelect(ByVal e As TreeViewEventArgs)
        MyBase.OnAfterSelect(e)
        RaiseEvent DirectorySelected(Me, _
            New DirectorySelectedEventArgs(e.Node.FullPath))
    End Sub
End Class
Public Class DirectorySelectedEventArgs
    Inherits EventArgs
    Public DirectoryName As String
    Public Sub New(ByVal DirectoryName As String)
        Me.DirectoryName = DirectoryName
    End Sub
End Class

The sophistication of this code shows you the level of expertise available in MacDonald's book. But, like many gurus, there are a couple of things that can trip up people who are not as familiar with .NET as MacDonald.

It's critically important to this specific code to add the DirectoryTree Class to an existing project (for example, a project created with the Windows Application template) rather than creating it in a separate project. Otherwise, when the control is created with a Dim statement, VB .NET requires a Namespace and a Type, not just a Type as in MacDonald's example.

Specifically, MacDonald's suggested code ...

Private Sub Form1_Load( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles MyBase.Load
    Dim DirTree As New DirectoryTree
    DirTree.Size = New Size(Me.Width - 30, Me.Height - 60)
    DirTree.Location = New Point(5, 5)
    DirTree.Drive = "C"
    Me.Controls.Add(DirTree)
End Sub

... will generate an error on DirectoryTree because the statement requires a Type. If you place the class in a project by itself (In fairness, MacDonald clarifies all this two chapters later), you have to add a Reference to the project and qualify the Dim statement as Namespace.Type. For example:

Dim DirTree As New MyDirNameSpace.DirectoryTree

A reference Systems.Windows.Forms also has to be added to a 'stand alone' class project.

The 'option' of changing this class to work in the VB .NET Designer is compelling and there is more about in the book ... again two chapters later. But MacDonald never spells out exactly what to do.

In order to get this new DirectoryTree control to function as a control in the Designer, we first have to add a standard TreeView control from the VB Toolbox to our project. The VB .NET designer adds code in the hidden Region to support the TreeView control when we do this.

Now, add a Reference to the Namespace that our new DirectoryTree control is in. Then open the normally hidden Region code added by VB .NET and ignore the warning at the top and change the Designer code directly. The graphic below shows the two statements that have to be changed to your 'Namespace.Class'. (I used MyDirNameSpace.DirectoryTree.) For many purposes, this may not be a very efficient thing to do because this does not add it to the toolbox and these changes, in general, are good only for this project.

Changing the Designer

Once this is done, you discover that the new property that was added (Drive) is now included in the properties window and you can change the Drive displayed in the DirectoryTree right there. More interesting, however, is the fact that the code that displays the DirectoryTree gets executed at design time and is visible in the design time Directory View Control. You can even expand subdirectories at design time.

New DirectoryTree

Preventing this behavior is part of a larger discussion that MacDonald devotes an entire later chapter to. In brief, you test for design time in the Set statement that is in the class code and prevent the display update code for design time. MacDonald has other great advice for people who want to produce production quality controls as well.

Explore Visual Basic
By Category
About.com Special Features

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

Easy ways to connect two computers for networking purposes. More >

  1. Home
  2. Computing & Technology
  3. Visual Basic

©2009 About.com, a part of The New York Times Company.

All rights reserved.