Link to home
Start Free TrialLog in
Avatar of kingman1
kingman1

asked on

Using ImageList in Custom TreeView Control

I am creating a custom control in Visual Basic 2008 that inherits the TreeView control. I added an ImageList control from the toolbox and inserted 6 images for various drives and folders.

The control will display a folder hierarchy based on the path given.

My problem is when I add the control to a form and run it the images do not appear for the nodes.

Am I missing something?

Here is the relevant code, I think, if that helps:

Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.ComponentModel
Imports System.IO
Imports System.Runtime.InteropServices

Public Class asDirectoryViewer

    Inherits TreeView

    Private components As System.ComponentModel.IContainer

' .... My Properties and Functions

Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(asDirectoryViewer))
        Me.imlDriveTree = New System.Windows.Forms.ImageList(Me.components)
        Me.SuspendLayout()
        '
        'imlDriveTree
        '
        Me.imlDriveTree.ImageStream = CType(resources.GetObject("imlDriveTree.ImageStream"), System.Windows.Forms.ImageListStreamer)
        Me.imlDriveTree.TransparentColor = System.Drawing.Color.Transparent
        Me.imlDriveTree.Images.SetKeyName(0, "Network_Drive.ico")
        Me.imlDriveTree.Images.SetKeyName(1, "HardDrive.ico")
        Me.imlDriveTree.Images.SetKeyName(2, "disc drive.ico")
        Me.imlDriveTree.Images.SetKeyName(3, "Removable.ico")
        Me.imlDriveTree.Images.SetKeyName(4, "Folder.ico")
        Me.imlDriveTree.Images.SetKeyName(5, "Open.ico")
        '
        'asDirectoryViewer
        '
        Me.ImageList = imlDriveTree
        '
        Me.ResumeLayout(False)

    End Sub


    Protected Overrides Sub Finalize()
        Me.Nodes.Clear()
        MyBase.Nodes.Clear()
        MyBase.Finalize()
    End Sub

End Class


I can't figure out why the images for the nodes are not showing up at runtime.


Thanks,

Terry
Avatar of Nasir Razzaq
Nasir Razzaq
Flag of United Kingdom of Great Britain and Northern Ireland image

Where are you setting the images?

Try this example

http://www.codeproject.com/KB/tree/FileSystemTreeView.aspx
Avatar of kingman1
kingman1

ASKER

I added the images to the ImageList using the Collections dialog in the ImageLists property window. I want the images compiled with the control so the user does not have to supply them.
But you need to assign the images to the nodes as well. Just adding the images to the image list wont work.
In the InitializeComponent sub I set the controls imagelist property to the imagelist.

Here is the code that adds the nodes and sets the images: in this case 4 and 5



Private Sub AddAllFolders(ByVal TNode As TreeNode, ByVal FolderPath As String)
        Try
            For Each FolderNode As String In Directory.GetDirectories(FolderPath)
                Dim SubFolderNode As TreeNode = TNode.Nodes.Add(FolderNode.Substring(FolderNode.LastIndexOf("\"c) + 1), FolderNode.Substring(FolderNode.LastIndexOf("\"c) + 1), 4, 5)

                If FolderNode.EndsWith("\") Then
                    SubFolderNode.Tag = FolderNode
                Else
                    SubFolderNode.Tag = FolderNode & "\"
                End If

                SubFolderNode.Nodes.Add("Loading...")
            Next
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Folder TreeView", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

Open in new window

Along with setting the ImageList property of the tree, you need to set the ImageIndex property of each node.

SubFolderNode.ImageIndex = 2

http://msdn.microsoft.com/en-us/library/system.windows.forms.treenode.imageindex.aspx
OK I updated my code as follows but it still does not show the images.


Private Sub AddAllFolders(ByVal TNode As TreeNode, ByVal FolderPath As String)
        Try
            For Each FolderNode As String In Directory.GetDirectories(FolderPath)
                Dim SubFolderNode As TreeNode = TNode.Nodes.Add(FolderNode.Substring(FolderNode.LastIndexOf("\"c) + 1), FolderNode.Substring(FolderNode.LastIndexOf("\"c) + 1), 4, 5)

                If FolderNode.EndsWith("\") Then
                    SubFolderNode.Tag = FolderNode
                Else
                    SubFolderNode.Tag = FolderNode & "\"
                End If

                SubFolderNode.Nodes.Add("Loading...")
                SubFolderNode.ImageIndex = 4
                SubFolderNode.SelectedImageIndex = 5
            Next
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Folder TreeView", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

Open in new window

In your original code, you only have SetKeyName method calls for the imagelist. Do you actually add images in the image list? Are you able to see the images in the list in designer? Attach a screenshot.
Yes, I added the images to the imagelist. The code below was automatically inserted by Visual Studio. I did not add it. I have also attached the requested screen shot.

Sorry for all the trouble. I really do appreciate the help. I am new to control programming in .net, this is my first attempt at creating a custom control.
Me.imlDriveTree.ImageStream = CType(resources.GetObject("imlDriveTree.ImageStream"), System.Windows.Forms.ImageListStreamer)
        Me.imlDriveTree.TransparentColor = System.Drawing.Color.Transparent
        Me.imlDriveTree.Images.SetKeyName(0, "Network_Drive.ico")
        Me.imlDriveTree.Images.SetKeyName(1, "HardDrive.ico")
        Me.imlDriveTree.Images.SetKeyName(2, "disc drive.ico")
        Me.imlDriveTree.Images.SetKeyName(3, "Removable.ico")
        Me.imlDriveTree.Images.SetKeyName(4, "Folder.ico")
        Me.imlDriveTree.Images.SetKeyName(5, "Open.ico")

Open in new window

DirectoryViewer.jpg
It should work.  Try to read through this example to see if you can spot any problem in your code

http://www.codeproject.com/KB/tree/UsingTreenodes.aspx
I still can't seem to get it to work, however I did find a work-around that works. It requires the user to add an imagelist control and assign it to the DirectoryViewer Control. They then have to call the following method in the form_load event.

DiretoryViewer1.SetImageList(ImageList2)

The code for the method is below.

Is there a way to run this method when the user assigns an imagelist to the ImageList property so they don't have to call the method? I tried doing an override of the imagelist property but it says it is protected.
Public Sub SetImageList(ByVal imlList As ImageList)

        imlList.TransparentColor = System.Drawing.Color.Transparent
        imlList.Images.Add(My.Resources.OSDrive_32)
        imlList.Images.Add(My.Resources.HardDrive_28)
        imlList.Images.Add(My.Resources.DiscDrive_26)
        imlList.Images.Add(My.Resources.Removable_40)
        imlList.Images.Add(My.Resources.NetworkDrive_29)
        imlList.Images.Add(My.Resources.ClosedFolder_034)
        imlList.Images.Add(My.Resources.OpenFolder_033)

    End Sub

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Nasir Razzaq
Nasir Razzaq
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I modified my code as suggested and it works. See below.

Thanks for the help. I appreciate it.
Public Sub SetImageList()

        Dim imlList As New ImageList

        imlList.TransparentColor = System.Drawing.Color.Transparent
        imlList.Images.Add(My.Resources.OSDrive2_32)
        imlList.Images.Add(My.Resources.HardDrive_28)
        imlList.Images.Add(My.Resources.DiscDrive_26)
        imlList.Images.Add(My.Resources.Removable_40)
        imlList.Images.Add(My.Resources.NetworkDrive_29)
        imlList.Images.Add(My.Resources.ClosedFolder2_034)
        imlList.Images.Add(My.Resources.OpenFolder2_033)

        MyBase.ImageList = imlList
        Me.ImageList = imlList

    End Sub

Open in new window

Glad your problem is solved :-)