This tutorial is part of a series: Part 1 | Part 2![]()
In Part 1 of this tutorial series, I presented a way to use the .NET TreeView control as a file browser similar to Windows Explorer in functionality. As we navigate through this TreeView, the BeforeExpand event is handled so that each node is dynamically populated as soon as it gets expanded.
The second part of this tutorial focuses on displaying the native system icons for each file and folder in the TreeView.
Getting Started
We will continue building upon the TreeView File Browser Component from Part 1. Open the project and let’s get started.
Implement SHGetFileInfo()
Add a new Module to your project. It should have the default name of Module1.vb.
Copy/paste the following code into Module1.vb:
Public Declare Auto Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As IntPtr
Public Const SHGFI_ICON As Integer = &H100
Public Const SHGFI_SMALLICON As Integer = &H1
Public Const SHGFI_LARGEICON As Integer = &H0
Public Const SHGFI_OPENICON As Integer = &H2
Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As Integer
<Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=260)> _
Public szDisplayName As String
<Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=80)> _
Public szTypeName As String
End Structure
This is a simple implementation of the Win32 API call SHGetFileInfo, which can do more than just help us retrieve icons from the Windows shell. You can read more about it on the web.
In the code above, we have declared SHGetFileInfo (line 1), a function native to Windows which is stored in it’s own shell32.dll file. By implementing this API call in our code, we can tap into the same function that Windows uses to retrieve the actual system icons for files and folders.
A single folder icon consists of several images
SHGetFileInfo needs to know whether we are requesting an icon at all (because we can actually request things other than an icon). It also needs to know whether it is a small icon (16×16), a large icon (full size), as well as whether the icon is in the open state (such as when a folder appears open in Windows Explorer), so we have defined the constants for these (line 3-6).
Furthermore, the SHGetFileInfo needs something to store the result of our request (in this case, the icon), so we must supply it with an SHFILEINFO structure (line 8-16).
Create a wrapper function to make using SHGetFileInfo easier
The important thing to understand about Win32 API calls is that they sometimes do not return values in the exact format we need them in. For example, SHGetFileInfo does not return a simple System.Drawing.Image or System.Drawing.Icon that we can use immediately in .NET code. Therefore, we will have to extract the returned values from the SHFILEINFO structure and convert them into the desired .NET objects. Basically, we need a wrapper function.
The wrapper function should call SHGetFileInfo, extract the icon from the SHFILEINFO structure and convert it to a System.Drawing.Image, then return the System.Drawing.Image. GetShellIconAsImage will be our wrapper function that wraps up the logic which will make this all happen.
Copy/paste the following code into Module1.vb:
' GetShellIconAsImage
Function GetShellIconAsImage(ByVal argPath As String) As Image
Dim mShellFileInfo As New SHFILEINFO
mShellFileInfo.szDisplayName = New String(Chr(0), 260)
mShellFileInfo.szTypeName = New String(Chr(0), 80)
SHGetFileInfo(argPath, 0, mShellFileInfo, System.Runtime.InteropServices.Marshal.SizeOf(mShellFileInfo), SHGFI_ICON Or SHGFI_SMALLICON)
' attempt to create a System.Drawing.Icon from the icon handle that was returned in the SHFILEINFO structure
Dim mIcon as System.Drawing.Icon
Dim mImage as System.Drawing.Image
Try
mIcon = System.Drawing.Icon.FromHandle(mShellFileInfo.hIcon)
mImage = mIcon.ToBitmap
Catch ex As Exception
' for some reason the icon could not be converted so create a blank System.Drawing.Image to return instead
mImage = New System.Drawing.Bitmap(16, 16)
End Try
' return the final System.Drawing.Image
Return mImage
End Function
Let us understand what is going on in this function.
First, we define the GetShellIconAsImage function (line 2), which accepts a single argument for the path of the file whose icon we wish to retrieve.
We then instantiate a new SHFILEINFO structure (line 3) and fill it with some required data (line 4-5). Basically, we must stuff the szDisplayName and szTypeName properties of the SHFILEINFO structure with blank strings before passing it to SHGetFileInfo, otherwise the structure will be of the wrong size and appear as garbage to SHGetFileInfo. A tad bit strange, but this is common with the Win32 API…
Next we call SHGetFileInfo with several parameters (line 6). You can see that we pass in our SHFILEINFO structure, which will get populated with file information after SHGetFileInfo executes.
Finally, we attempt to convert the icon handle in the SHFILEINFO structure to a System.Drawing.Icon, using the System.Drawing.Icon.FromHandle function (line 11). We then convert the System.Drawing.Icon to a System.Drawing.Image (line 12) because this is what .NET likes most. If this procedure fails, we just return a blank System.Drawing.Image (line 15).
We now have a method of retrieving an icon from the Windows shell as a System.Drawing.Image, but where do we store all of these icons, how do we know which icons to retrieve, and when?
Caching the icons for repeated use and quicker access
If you recall back to part one, nodes are populated on demand, meaning every time a user expands a node we request a new listing from the underlying filesystem. This is great, because as we are adding each child node, we can also retrieve the icon from the Windows shell using our wrapper function GetShellIconAsImage, then apply this icon to the node’s ImageKey property before adding it to the TreeView.
Since the TreeView control supports displaying icons from an ImageList, we are going to cache the icons from the Windows shell and store them in an ImageList that is bound to the TreeView control. This caching process should appear straightforward in just a moment.
Open UserControl1 in Design Mode and add an ImageList control from the ToolBox. It should have the default name of ImageList1.
We now want to bind this ImageList control to our TreeView control. Select the TreeView1 control and change it’s ImageList property to ImageList1. The TreeView is now able to display images from ImageList1.
Add the following code to UserControl1.vb:
Function CacheShellIcon(ByVal argPath As String) As String
Dim mKey As String = Nothing
' determine the icon key for the file/folder specified in argPath
If IO.Directory.Exists(argPath) = True Then
mKey = "folder"
ElseIf IO.File.Exists(argPath) = True Then
mKey = IO.Path.GetExtension(argPath)
End If
' check if an icon for this key has already been added to the collection
If ImageList1.Images.ContainsKey(mKey) = False Then
ImageList1.Images.Add(mKey, GetShellIconAsImage(argPath))
End If
Return mKey
End Function
When adding an Image to an ImageList, we can supply a unique key (line 4-8) that can be used to retrieve the Image later. Using this logic, we can store each icon that we cache from the Windows shell in the ImageList using a key equal to the file’s extension (line 11). For example, when the icon gets cached for a Text File, we add it to the ImageList using .txt as the key. The next time we encounter a Text File, we check if the ImageList already contains a .txt key (line 10), if so we skip the file since the icon has already been cached.
At this point, we haven’t actually associated any cached icons with a node in the TreeView. Let’s do that now.
Modify the UserControl1_Load event and include these lines of code:
mRootNode.ImageKey = CacheShellIcon(RootPath) mRootNode.SelectedImageKey = mRootNode.ImageKey
Modify the TreeView1_BeforeExpand event and include these lines of code:
mDirectoryNode.ImageKey = CacheShellIcon(mDirectory.FullName) mDirectoryNode.SelectedImageKey = mDirectoryNode.ImageKey
What about the “open folder” icon?
You may have noticed that when you select a folder in Windows Explorer and it becomes highlighted, the icon also changes to one where the folder appears to be “open” rather than closed. Remember earlier when we defined SHGFI_OPENICON? We simply supply this constant in the uFlags parameter of the SHGetFileInfo call in our GetShellIconAsImage method.
Take a look at the original call to SHGetFileInfo:
SHGetFileInfo(IO.Path.GetTempPath, 0, mShellFileInfo, System.Runtime.InteropServices.Marshal.SizeOf(mShellFileInfo), SHGFI_ICON Or SHGFI_SMALLICON)
If you change the uFlags parameter from this:
SHGFI_ICON Or SHGFI_SMALLICON
To this:
SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_OPENICON
You can retrieve the small open icon. Here’s a simple way to implement this in your current component.
Make a copy of your original GetShellIconAsImage method and name it GetShellOpenIconAsImage. The only thing different about this method is that you want to supply SHGFI_OPENICON in the uFlags parameter as I have described above.
The next thing to do is modify the CacheShellIcon method to include this line after the one that is similar to it:
ImageList1.Images.Add(mKey & "-open", GetShellOpenIconAsImage(argPath))
Displaying Files in the TreeView
Up to this point, we’ve only been displaying folders in the TreeView because this is how Windows Explorer does it. Windows Explorer has a separate panel for displaying the contents of the selected folder. However, let’s not reinvent the wheel. My goal in these tutorials is to show you the code and the logic that makes these ideas work, but it’s your job to apply them to your own projects in your own way.
What we are going to do instead is display the files directly in the TreeView. All we need to do is include a second loop in the TreeView1_BeforeExpand event to populate the files. Just copy/paste the loop block that we used for populating folders, and modify it for files like so:
' add each file from the file system that is a child of the argNode that was passed in For Each mFile As IO.FileInfo In mNodeDirectory.GetFiles ' declare a TreeNode for this file Dim mFileNode As New TreeNode ' store the full path to this file in the file TreeNode's Tag property mFileNode.Tag = mFile.FullName ' set the file TreeNodes's display text mFileNode.Text = mFile.Name mFileNode.ImageKey = CacheShellIcon(mFile.FullName) mFileNode.SelectedImageKey = mFileNode.ImageKey & "-open" ' add this file TreeNode to the TreeNode that is being populated e.Node.Nodes.Add(mFileNode) Next
What fun would this tutorial be without being able to double click the files to open them? Handle the TreeView1_NodeMouseDoubleClick event in UserControl1 like so:
Private Sub TreeView1_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
' only proceed if the node represents a file
If e.Node.ImageKey = "folder" Then Exit Sub
If e.Node.Tag = "" Then Exit Sub
' try to open the file
Try
Process.Start(e.Node.Tag)
Catch ex As Exception
MessageBox.Show("Error opening file: " & ex.Message)
End Try
End Sub
Here it is in action:
![]()

Glass Ocean is Perry Butler's Blog, Music Productions, Services, and Software Development.
Thanks a lot for this tutorial. It is great but i have an issue, maybe you can explain…
i am using windows 7 pro.
when displaying icons no matter if it is a file or a folder it alsways displays the window icon (flying window).
What am i done wrong? any idea? i was trying to solve it myself but the only thing i discovered is that the imagelist control has set the property “Images:(Collection)” but there is no images into the collection.
OscarG
OscarG, I have not done much development or testing in Windows 7, so unfortunately I cannot answer your question at this time.
You might want to check out the Windows API Code Pack for Microsoft .NET Framework, which does mention this:
One of the features listed for the API Code Pack that you might be interested in:
Perry,
Thanks for this tutorial and the previous one, it is just what I needed for my file browser. I have one problem however I cannot get the open folder to work. I believe I copied the code correctly, Here is my function
Function GetShellOpenIconAsImage(ByVal argPath As String) As Image
Dim mShellFileInfo As New SHFILEINFO
mShellFileInfo.szDisplayName = New String(Chr(0), 260)
mShellFileInfo.szTypeName = New String(Chr(0), 80)
SHGetFileInfo(argPath, 0, mShellFileInfo, System.Runtime.InteropServices.Marshal.SizeOf(mShellFileInfo), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_OPENICON)
‘ attempt to create a System.Drawing.Icon from the icon handle that was returned in the SHFILEINFO structure
Dim mIcon As System.Drawing.Icon
Dim mImage As System.Drawing.Image
Try
mIcon = System.Drawing.Icon.FromHandle(mShellFileInfo.hIcon)
mImage = mIcon.ToBitmap
Catch ex As Exception
‘ for some reason the icon could not be converted so create a blank System.Drawing.Image to return instead
mImage = New System.Drawing.Bitmap(16, 16)
End Try
‘ return the final System.Drawing.Image
Return mImage
End Function
How does the micon line 11 work? How does it know it is the open icon and not the closed one.
Thanks for your help.
Nick
Nick,
My apologies, you should have seen another line of code, but a problem with my website was preventing that line of code from being displayed in the tutorial (apparently I’m using SyntaxHighlighter Devovled.) Basically, it’s the code that adds the OPENICON to the ImageList for use by our TreeView, and without it you won’t see the icons.
I would encourage you to check out the tutorial again as I have fixed the missing code, particularly making sure that you implement this line of code properly:
Hello Perry, first of all: Very well done!!!
It’s exactly what I was looking for. But I have some problems implementing it.
1. I did part 1 of your tutorial and it worked exactly the way you’d descriped it. I referenced it just by adding your treeview_project to my project and the Usercontrol1 appeared in the Toolboxlist as expected (and worked). But after I did part 2 of your tutorial, it doesn’t work any longer. Usercontrol1 appears in the toolboxlist but trying to put it in my windowsform, nothing happens!? No exception or warning.
2. The events from Usercontrol1 don’t work. I tried “click”,”doubleclick”,”enter”,”keydown”,etc. – only the load-event reacts. I don’t know yet how to get the actual selected path from the Control by clicking on a node/folder to do something in my project.
Hope, you can help me with that,
Thanks
PS: Using vs2008, windows 7
Hello, me again.
I solved the Problem with the toolboxlist. Don’t ask me what it was, but after deleting and re-adding the usercontrol1-project in my project a few times, it (for no reason) worked again.
I also found out, what’s the problem with the event-handlers. If I set the Dock-Property not to “Fill”, so that the usercontrol1 is dividedin a treeview-area and an empty area, the events react – but only on the empty area. I think it’s because the treeview in the usercontrol1 has it’s own eventhandlers. But I can’t use them because i need the events in my project/windowsform and not within the treeview-control itself.
Does anyone know, how to solve this?
I have a windows form with the usercontrol1 on the left side and a datagridview on the right side showing a list of images that are in the folder, that is selected on the left side (usercontrol). So everytime the selected folder changes I need to actualice the datagridview.
Thanks
PS: I encounterd another Problem in windows 7 (and as I found out in the net also in windows vista): Openning special folders like “…\applicationdata” or “\documentions and settings” throws exceptions: “file access denied”.
Thomas, My apology for the confusion. I should have posted the VS project files for this tutorial so you can have a working reference point. You can now download the VS project files the end of the tutorial.
To answer your question about the events, you need to expose the TreeView1 control publicly so you can access it through UserControl1 via a property or subroutine.
For example, in UserControl1 you can write a public Function to expose something about TreeView1:
Now when you recompile the UserControl1 and then add it to a WinForm, you can display the selected path using:
I hope this helps!
Concerning Windows 7, I have just started using it myself and have noticed that in many of my Visual Studio projects where I am accessing a common path on the system (Program Files, Documents and Settings), I also receive an Access Denied message where it used to work on Windows XP. This might be from the new User Access Control (UAC), or perhaps we need to use a different method to access those paths, such as environment variables (%USERPROFILE%). I do know that Windows 7 has changed where User profiles store data (C:\Users now instead of C:\Documents and Settings), but beyond this, I haven’t done much testing yet.
sir am sorry for inconvinence but i want your help i did what u have illustrated previosly but i want u to show me how can do this :
i have (import botton ) when i click it should save the selected item on the specific node the node should have the ability to save all typ of data and should be saved in a data base too,then should show me the items on listview as soon as i click on listview item should display the selected item then i want the dso former control ,pdf ,picturebox and media player to link them to work with listview items
thank you sir ..
Good tutorial, I was about to implement my tree with recursion until I came across your example. Seems cleaner this way. Thanks for sharing.
Hello, i have manged to get in all working. But what code do i need to get this to open from a button on a different form??
Thanks
VB 2008
Any help would be great.
Callum, just add a reference to the DLL or the entire Project, then you will be able to drag & drop UserControl1 from the Toolbox onto a Windows Form. Let me know if you still can’t get it working…
Perry, Thank you for posting this great code. This is by far the best explanation how to use TreeView. I got this working perfectly. However I would like to populate TreeView after user selects Output Folder instead of setting C:\ as root directory and refresh TreeView after event is completed
I am new to VB.net, my experience is mostly with VBA and VBS
I hope you can point me into the right direction. Thank you
Peter, the code which initializes the TreeView is in the UserControl1_Load event (from Part 1 of this tutorial). I would suggest placing this code into its own Sub (you might call this Sub InitializeRoot) and then you can call InitializeRoot whenever you need to (such as when the RootPath property is changed, or when the control is loaded via UserControl1_Load). You’ll also want to do a TreeView1.Nodes.Clear() to the InitializeRoot() method.
So, UserControl1_Load simply becomes:
Private Sub UserControl1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load InitializeRoot() End SubYour RootPath property should also call InitalizeRoot() whenever the value changes:
Property RootPath as String Get Return mRootPath End Get Set(value as String) mRootPath = value InitializeRoot() End Set End PropertyAnd finally, InitializeRoot(), which borrows code from the old UserControl1_Load event but also clears the nodes before populating again:
Private Sub InitializeRoot() ' when our component is loaded, we initialize the TreeView by adding the root node Dim mRootNode as New TreeNode mRootNode.Text = RootPath mRootNode.Tag = RootPath mRootNode.Nodes.Add("*DUMMY*") TreeView1.Nodes.Clear() TreeView1.Nodes.Add(mRootNode) End SubHopefully that points you in the right direction…
Thank you, I got this working. However there is small issue. mRoothPath is provided by a user after form loads, After loading form, TreeView shows small plus sign and if you click on it application crushes due to “Null Reference” (since no path was specified yet). I supposed best approach will be to have some error message displayed “please select folder” or hide this plus sign completely if its even possible.
I had to change mRoothPath to myRootPath, because I was getting some error messages.
I was also able to populate TreeView using some different method, but your one is much much faster
Thank you again
Hi Perry,
Thank you for this wonderful code. I do have a small…actually a rather big question. I managed to add this very important component to my application (It’s a replacement shell for explorer.exe). Users need to select different folders, such as My Music etc. and not only C: and Program Files. Only rootpath seems to be malfunctioning, It doesn’t change to the specified folder the user want. I hope you could help me.
Thank You,
Robert
Robert, have a look at my reply to Peter, earlier in these comments. He had nearly the same question. Let me know if this doesn’t achieve what you’re after.
Hi Perry,
Thank you for the tip, but I have a quite different issue. I made some buttons in a form where users can select there folder. It’s not in the usercontrol itself, but in a form which use the .dll from the usercontrol. So, theoretically only: Private mRootPath As String = “path user needs”, needs to be adapted if you click the button.
I thought you can do this in the form itself by make the mouse-click handler (you know, simple as that) and type this: Usercontrol1.Roothpath = “C:Windows” and then Usercontrol.refresh() or something like that. But when I do that, nothing happens. RoothPath can only be changed in the properties window.
I hope you can follow my story and my problem.
Thank You,
Robert
Robert, to allow a user to change RootPath dynamically, you need to modify the UserControl1 code slightly as follows:
UserControl1_Load simply becomes:
Private Sub UserControl1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load InitializeRoot() End SubYour RootPath property should also call InitalizeRoot() whenever the value changes:
Property RootPath as String Get Return mRootPath End Get Set(value as String) mRootPath = value InitializeRoot() End Set End PropertyAnd finally, InitializeRoot(), which borrows code from the old UserControl1_Load event but also clears the nodes before populating again:
Private Sub InitializeRoot() ' when our component is loaded, we initialize the TreeView by adding the root node Dim mRootNode as New TreeNode mRootNode.Text = RootPath mRootNode.Tag = RootPath mRootNode.Nodes.Add("*DUMMY*") TreeView1.Nodes.Clear() TreeView1.Nodes.Add(mRootNode) End SubAnd then you can set the RootPath property of the UserControl1 object at runtime (using a CommandButton or something) and the TreeView will update itself automatically.
Hi Perry,
Let me first say that this is a very useful piece of code.
When I use this code in Windows 7 and set the root path to C:\ or Desktop, I am getting icons for the folders that look like drive icons, or the desktop icon. If I set rootpath to a folder like C:\program files, the icons for folders are correct. Any ideas on how I can make the icons display correctly for Drives, Desktop, etc, while still keeping the correct icon for folders?
Thank you
Ryan
Please check my reply to Stephane in these comments, which explains how to fix this bug.
Hi Peery,
Thank you very much for your code. Very Helpful.
I have a couple of minor problems:
1) By Changing the root to C:\ makes the icon of the drive, and of every folder thereafter a drive icon, so it is asociating c:\ as a folder, and think that due to cashing, all the other folders as well. solution?
2) I would like to display in the treeview my network drives also. what changes do I need?
thanks
Ignacio
Hi Ignacio, 1) is due to a bug that doesn’t handle drive icons. See the rest of these comments (Rick or Stephane) for a fix. I can’t help you with 2) right this moment, so perhaps I will include it in tutorial part 3.
When the root is C:\ it’s property is “Local Disk” not “folder”, so the code is matching the mKey “folder” to the image for “Local Disk”. So all the real folders show up as drive icons.
Here is a solution that I found.
In CacheShellIcon
change this line:
If IO.Directory.Exists(argPath) = True Then
mKey = “folder”
to this:
If IO.Directory.Exists(argPath) = True Then
If argPath = IO.Directory.GetDirectoryRoot(argPath) Then
mKey = “Local Disk”
Else
mKey = “folder”
End If
This is all new to me so there may be a better way to do this.
Thanks Rick, excellent fix.
Thanks for this exceptional tutorial, it has proven most useful so far. One thing I’m having trouble with, and I’m not the most experienced when it comes to VB, is getting this user control let the program form manage the onclick. In other words, the program I’m inserting this control into, I want IT to manage what happens when I click on a file/folder.
In your example, you can double-click to open a file… I need my program to control what happens onclick or doubleclick. Is there a way to do that? Thanks again!
Very Very Nice Code with good explanation. It’s useful in any project which deals with file browser etc.
Thank you very much; I was searching this since a while really.
Hey Perry,
Big thanks for the tutorial I’m building a self serve portal for users to an easier view ACL’s on folder and it’s work beautifully using DirectorySecurity and AuthorizationRuleCollection.
However in my TreeView all my icons disaply correctly for files! but for folders then all show up as the “Drive” icon…
I’m on windows 7 but issue seems different dans Oscars?
any ideas?
thanks
Stephane, thank you for pointing out this bug. Yes, it’s a BUG! I hope to fix this in tutorial part 3. I know…it has been a long time since part 2, as I have been super busy getting my freelance business off the ground so I don’t have to work two jobs during these tough times. I do regret not having part 3 available sooner because I’m still getting hundreds of hits a month for this tutorial and I know people need the info, as I desperately did at one time.
I may be able to help you though, I did some code modifications that fixed it for me in Windows 7 (32-bit). The reason this bug happens is because of the logic in the CacheShellIcon function. Basically it does not handle drive icons at all, but a folder icon is cached for a drive, because a drive is also a folder and so it satisfies the conditional statement.
To fix this, I modified the CacheShellIcon function to check if the path is a drive BEFORE assuming it is a folder (which would always equal true):
Function CacheShellIcon(ByVal argPath As String) As String Dim mKey As String = Nothing ' determine the icon key for the file/folder specified in argPath If IO.Directory.Exists(argPath) = True Then If argPath = IO.Directory.GetDirectoryRoot(argPath) Then mKey = "drive" Else mKey = "folder" End If ElseIf IO.File.Exists(argPath) = True Then mKey = IO.Path.GetExtension(argPath) End If ' check if an icon for this key has already been added to the collection If ImageList1.Images.ContainsKey(mKey) = False Then ImageList1.Images.Add(mKey, GetShellIconAsImage(argPath)) If mKey = "folder" Then ImageList1.Images.Add(mKey & "-open", GetShellOpenIconAsImage(argPath)) End If Return mKey End FunctionSpecial thanks to Rick who posted this fix much sooner!
Hi Perry,
Than kyou for your code. It’s working good and with icons.
But I’m stuck using it on a windows form application . The Icons wont show.
I’ve added Form1.vb to your project. Copied usercontrol content into Form1.vb, and in designer I added the textbox, button, treeview, imagelist, and colordialog.
The Form1 filebrowser works, but the ICONS does not show. I just have the standard + signs in the treeview.
I’m probably missing something here, Could you point me in the right direction, on using your code it in another windows form?
Thank you very much.
Per
Per, thanks for writing. You said it’s “working good and with icons”, I assume that is when you Build the application in Visual Studio and it loads into the “Test Container”?
First check: In the Properties for the TreeView control, make sure the ImageList property is set to ImageList1 (or whatever your ImageList is named).
When you create the TreeView UserControl per the tutorial, it encapsulates the ColorDialog and the ImageList for you, so all you need is to add the TreeView UserControl to a Windows form. Perhaps you were trying to copy the code from the UserControl’s code file into a Form’s code file, or building the TreeView directly in a Windows form, which is sort of reverse engineering the usefulness of the UserControl! I recommend that you try the UserControl because it’s re-usable.
Here’s how it works…
I added a Windows form to the TreeView project and opened it in the designer. From the Toolbox I was able to drag the TreeView UserControl straight into the Windows form and it appeared immediately (with icons) in the designer.
If you have a separate project and you wish to use the TreeView UserControl, you can add it to that project. With your new Windows form project open, in the Toolbox, right click anywhere and select “Choose Items…”, click “Browse…”, locate your TreeView UserControl’s DLL file (usually in your TreeView project’s bin/debug folder), then click “OK”. This will add “UserControl1″ to the Toolbox and you may drag it onto your Windows form.
Though, that won’t allow you to modify the internal code of the TreeView UserControl. If you want to modify it while developing a separate project without hassle, you can always add the TreeView UserControl project to your current project (via File -> Add -> Existing Project…). This will give you direct access to using the TreeView UserControl in your project from the Toolbox, as well as the ability to change your TreeView UserControl code and rebuild it. Therefore when you change your TreeView UserControl, Visual Studio will rebuild the control for you and the new one is automatically used in your current project. I have found this to be the most useful way to manage solutions with more than one custom control.
Please write back if that doesn’t help.
First of all, good work! and a million thanks, this has helped me a lot!.
I just wanted to add, that i needed to find a solution to fix the horrible exception thrown when accesing a protected/system directory under win7 or vista. So what I did was to modify the TreeView1_BeforeExpand sub and enclosed both For Each in a Try Catch block like this:
Try
For Each mDirectory As IO.DirectoryInfo In mNodeDirectory.GetDirectories
…
Next
For Each mFile As IO.FileInfo In mNodeDirectory.GetFiles
…
Next
Catch ex As UnauthorizedAccessException
‘ Change node name to let know the user that he/she desn’t have enough permissions to list that directory
e.Node.Text = e.Node.Text & ” *Insufficient privilieges.*”
End Try
Now the control doesn’t throw any exception to the user, and he can know why he can’t list that particular directory.
Thanks again and best regards to all!
P.S. I forgot to tell you that I’m looking forward to part 3…