Treeview images problem...

  • Thread starter Thread starter Co
  • Start date Start date
C

Co

Hi All,

I have a problem with images in a Treeview.
I have a "closed folder" and "opened folder" set in the Treeview
settings but I also have two special
icons. A "closed folder with email" and an "opened folder with email",
they are index 3 and 4.
Now when I click a node and it has image 3 then it should show image 4
( the opened folder with email.)
That's working fine.
The problem is how can I change the image back to image 3 when I click
on another node?

Private Sub TreeView_AfterSelect(ByVal sender As Object, ByVal e As
System.Windows.Forms.TreeViewEventArgs) Handles TreeView.AfterSelect

'if the user has a subscription on the folder then show
the right icon
Dim tn As TreeNode = TreeView.SelectedNode
If tn.SelectedImageIndex = 3 Then
tn.SelectedImageIndex = 4
tn.ImageIndex = 4
End If

End Sub

Marco
 
Hi All,

I have a problem with images in a Treeview.
I have a "closed folder" and "opened folder" set in the Treeview
settings but I also have two special
icons. A "closed folder with email" and an "opened folder with email",
they are index 3 and 4.
Now when I click a node and it has image 3 then it should show image 4
( the opened folder with email.)
That's working fine.
The problem is how can I change the image back to image 3 when I click
on another node?

Private Sub TreeView_AfterSelect(ByVal sender As Object, ByVal e As
System.Windows.Forms.TreeViewEventArgs) Handles TreeView.AfterSelect

'if the user has a subscription on the folder then show
the right icon
Dim tn As TreeNode = TreeView.SelectedNode
If tn.SelectedImageIndex = 3 Then
tn.SelectedImageIndex = 4
tn.ImageIndex = 4
End If

End Sub

Marco

You can use the treeviews AfterCollapse and AfterExpand events...

Private Sub TreeView_AfterExpand (ByVal sender As Object, ByVal e As TreeViewEventArgs)
e.Node.SelectedImageIndex = 4
e.Node.ImageIndex=4
End Sub

Private Sub TreeView_AfterCollapse (ByVal sender As Object, ByVal e As TreeViewEventArgs)
e.Node.SelectedImageIndex = 3
e.Node.ImageIndex=3
End Sub

This becomes a little more complex if you have multiple types of nodes with
different open close images. In that case, I usually create a base node type,
and then create sub nodes that set the actual image indexs. Something like:

MustInherit Class MyTreeNodeBase
Inherits System.Windows.Forms.TreeNode

' constructors


Private _openIndex As Integer
Private _closeIndex As Integer

Protected Property OpenIndex As Integer
Get
Return _openIndex
End Get
Set (ByVal value As Integer)
_openIndex = value
End Set
End Property

Protected Property CloseIndex As Integer
Get
Return _closeIndex
End Get
Set (ByVal value As Integer)
_closeIndex = value
End Set
End Property

Public Sub SetOpenIcon()
Me.SelectedImageIndex = OpenIndex
Me.ImageIndex = OpenIndex
End Sub

Public Sub SetCloseIcon()
Me.SelectedImageIndex = CloseIndex
Me.ImageIndex = CloseIndex
End Sub
End Class

Class FolderNode
Inherits MyTreeNodeBase

Public Sub New ()
OpenIndex = 1
CloseIndex = 0
End Sub
End Class

Class EmailNode
Inherits MyTreeNodeBase

Pulbic Sub New()
OpenIndex = 4
CloseIndex = 3
End Sub

End Class

Then in the events, it would look something like:

Private Sub TreeView_AfterExpand (ByVal sender As Object, ByVal e As TreeViewEventArgs)
Dim tn As MyTreeNodeBase = TryCast (e.Node, MyTreeNodeBase)
If tn IsNot Nothing Then
tn.SetOpenIcon()
End If
End Sub

Private Sub TreeView_AfterCollapse (ByVal sender As Object, ByVal e As TreeViewEventArgs)
Dim tn As MyTreeNodeBase = TryCast (e.Node, MyTreeNodeBase)
If tn IsNot Nothing Then
tn.SetCloseIcon()
End If
End Sub

Anyway - keep in mind that this is all air code, so there could be some minor
syntactical errors in there :)
 
You can use the treeviews AfterCollapse and AfterExpand events...

Private Sub TreeView_AfterExpand (ByVal sender As Object, ByVal e As TreeViewEventArgs)
        e.Node.SelectedImageIndex = 4
        e.Node.ImageIndex=4
End Sub

Private Sub TreeView_AfterCollapse (ByVal sender As Object, ByVal e As TreeViewEventArgs)
        e.Node.SelectedImageIndex = 3
        e.Node.ImageIndex=3
End Sub

This becomes a little more complex if you have multiple types of nodes with
different open close images.  In that case, I usually create a base node type,
and then create sub nodes that set the actual image indexs.  Something like:

MustInherit Class MyTreeNodeBase
        Inherits System.Windows.Forms.TreeNode

        ' constructors

        Private _openIndex As Integer
        Private _closeIndex As Integer

        Protected Property OpenIndex As Integer
                Get
                        Return _openIndex
                End Get
                Set (ByVal value As Integer)
                        _openIndex = value
                End Set
        End Property

        Protected Property CloseIndex As Integer
                Get
                        Return _closeIndex
                End Get
                Set (ByVal value As Integer)
                        _closeIndex = value
                End Set
        End Property

        Public Sub SetOpenIcon()
                Me.SelectedImageIndex = OpenIndex
                Me.ImageIndex = OpenIndex
        End Sub

        Public Sub SetCloseIcon()
                Me.SelectedImageIndex = CloseIndex
                Me.ImageIndex = CloseIndex
        End Sub
End Class

Class FolderNode
        Inherits MyTreeNodeBase

        Public Sub New ()
                OpenIndex = 1
                CloseIndex = 0
        End Sub
End Class

Class EmailNode
        Inherits MyTreeNodeBase

        Pulbic Sub New()
                OpenIndex = 4
                CloseIndex = 3
        End Sub

End Class

Then in the events, it would look something like:

Private Sub TreeView_AfterExpand (ByVal sender As Object, ByVal e As TreeViewEventArgs)
        Dim tn As MyTreeNodeBase = TryCast (e.Node, MyTreeNodeBase)
        If tn IsNot Nothing Then
                tn.SetOpenIcon()
        End If
End Sub

Private Sub TreeView_AfterCollapse (ByVal sender As Object, ByVal e As TreeViewEventArgs)
        Dim tn As MyTreeNodeBase = TryCast (e.Node, MyTreeNodeBase)
        If tn IsNot Nothing Then
                tn.SetCloseIcon()
        End If
End Sub

Anyway - keep in mind that this is all air code, so there could be some minor
syntactical errors in there :)

Tom,

thanks a lot for your code.
I implemented it but still see no difference.
Should I change something from my original code.
Maybe remove the images from the settings of the treeview?

Marco
 
Tom,

thanks a lot for your code.
I implemented it but still see no difference.
Should I change something from my original code.
Maybe remove the images from the settings of the treeview?

Marco

Ok... Here is a working example. I have the treeview pointing to an imagelist
with 5 images in it.

Option Strict On
Option Explicit On

Public Class Form1

MustInherit Class ExpandableNode
Inherits System.Windows.Forms.TreeNode

Private _openIndex As Integer
Private _closeIndex As Integer

Protected Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
MyBase.New(text)
Me.OpenIndex = openIndex
Me.CloseIndex = closeIndex
SetCloseIcon()
End Sub

Protected Property OpenIndex() As Integer
Get
Return _openIndex
End Get
Set(ByVal value As Integer)
_openIndex = value
End Set
End Property

Protected Property CloseIndex() As Integer
Get
Return _closeIndex
End Get
Set(ByVal value As Integer)
_closeIndex = value
End Set
End Property

Public Sub SetOpenIcon()
Me.ImageIndex = OpenIndex
Me.SelectedImageIndex = OpenIndex
End Sub

Public Sub SetCloseIcon()
Me.ImageIndex = CloseIndex
Me.SelectedImageIndex = CloseIndex
End Sub
End Class

Class FolderNode
Inherits ExpandableNode

Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
MyBase.New(text, openIndex, closeIndex)
End Sub
End Class

Class EmailFolderNode
Inherits ExpandableNode

Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
MyBase.New(text, openIndex, closeIndex)
End Sub
End Class


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' set default image for nodes
TreeView1.SelectedImageIndex = 4
TreeView1.ImageIndex = 4

' create a folder node - with a child node
Dim fn As New FolderNode("A folder node", 1, 0)
fn.Nodes.Add(New TreeNode("a simple node"))
TreeView1.Nodes.Add(fn)

' create an email folder node - with a simple child node
Dim en As New EmailFolderNode("A email folder node", 2, 3)
en.Nodes.Add(New TreeNode("a simple node"))
TreeView1.Nodes.Add(en)
End Sub

Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
If tn IsNot Nothing Then
tn.SetOpenIcon()
End If
End Sub

Private Sub TreeView1_BeforeCollapse(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeCollapse
Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
If tn IsNot Nothing Then
tn.SetCloseIcon()
End If
End Sub
End Class
 
Tom,

thanks a lot for your code.
I implemented it but still see no difference.
Should I change something from my original code.
Maybe remove the images from the settings of the treeview?

Marco

Ok... Here is a working example. I have the treeview pointing to an imagelist
with 5 images in it.

Option Strict On
Option Explicit On

Public Class Form1

MustInherit Class ExpandableNode
Inherits System.Windows.Forms.TreeNode

Private _openIndex As Integer
Private _closeIndex As Integer

Protected Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
MyBase.New(text)
Me.OpenIndex = openIndex
Me.CloseIndex = closeIndex
SetCloseIcon()
End Sub

Protected Property OpenIndex() As Integer
Get
Return _openIndex
End Get
Set(ByVal value As Integer)
_openIndex = value
End Set
End Property

Protected Property CloseIndex() As Integer
Get
Return _closeIndex
End Get
Set(ByVal value As Integer)
_closeIndex = value
End Set
End Property

Public Sub SetOpenIcon()
Me.ImageIndex = OpenIndex
Me.SelectedImageIndex = OpenIndex
End Sub

Public Sub SetCloseIcon()
Me.ImageIndex = CloseIndex
Me.SelectedImageIndex = CloseIndex
End Sub
End Class

Class FolderNode
Inherits ExpandableNode

Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
MyBase.New(text, openIndex, closeIndex)
End Sub
End Class

Class EmailFolderNode
Inherits ExpandableNode

Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
MyBase.New(text, openIndex, closeIndex)
End Sub
End Class


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' set default image for nodes
TreeView1.SelectedImageIndex = 4
TreeView1.ImageIndex = 4

' create a folder node - with a child node
Dim fn As New FolderNode("A folder node", 1, 0)
fn.Nodes.Add(New TreeNode("a simple node"))
TreeView1.Nodes.Add(fn)

' create an email folder node - with a simple child node
Dim en As New EmailFolderNode("A email folder node", 2, 3)
en.Nodes.Add(New TreeNode("a simple node"))
TreeView1.Nodes.Add(en)
End Sub

Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
If tn IsNot Nothing Then
tn.SetOpenIcon()
End If
End Sub

Private Sub TreeView1_BeforeCollapse(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeCollapse
Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
If tn IsNot Nothing Then
tn.SetCloseIcon()
End If
End Sub
End Class
 
Ok... Here is a working example.  I have the treeview pointing to an imagelist
with 5 images in it.

Option Strict On
Option Explicit On

Public Class Form1

    MustInherit Class ExpandableNode
        Inherits System.Windows.Forms.TreeNode

        Private _openIndex As Integer
        Private _closeIndex As Integer

        Protected Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
            MyBase.New(text)
            Me.OpenIndex = openIndex
            Me.CloseIndex = closeIndex
            SetCloseIcon()
        End Sub

        Protected Property OpenIndex() As Integer
            Get
                Return _openIndex
            End Get
            Set(ByVal value As Integer)
                _openIndex = value
            End Set
        End Property

        Protected Property CloseIndex() As Integer
            Get
                Return _closeIndex
            End Get
            Set(ByVal value As Integer)
                _closeIndex = value
            End Set
        End Property

        Public Sub SetOpenIcon()
            Me.ImageIndex = OpenIndex
            Me.SelectedImageIndex = OpenIndex
        End Sub

        Public Sub SetCloseIcon()
            Me.ImageIndex = CloseIndex
            Me.SelectedImageIndex = CloseIndex
        End Sub
    End Class

    Class FolderNode
        Inherits ExpandableNode

        Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
            MyBase.New(text, openIndex, closeIndex)
        End Sub
    End Class

    Class EmailFolderNode
        Inherits ExpandableNode

        Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
            MyBase.New(text, openIndex, closeIndex)
        End Sub
    End Class

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' set default image for nodes
        TreeView1.SelectedImageIndex = 4
        TreeView1.ImageIndex = 4

        ' create a folder node - with a child node
        Dim fn As New FolderNode("A folder node", 1, 0)
        fn.Nodes.Add(New TreeNode("a simple node"))
        TreeView1.Nodes.Add(fn)

        ' create an email folder node - with a simple child node
        Dim en As New EmailFolderNode("A email folder node", 2, 3)
        en.Nodes.Add(New TreeNode("a simple node"))
        TreeView1.Nodes.Add(en)
    End Sub

    Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object,ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1..BeforeExpand
        Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
        If tn IsNot Nothing Then
            tn.SetOpenIcon()
        End If
    End Sub

    Private Sub TreeView1_BeforeCollapse(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeCollapse
        Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
        If tn IsNot Nothing Then
            tn.SetCloseIcon()
        End If
    End Sub
End Class

Tom,

sorry for being a newbie but I don't know how to fit the Form_load
code into my building up the Treeview reading from the database:

Private Sub LoadTree()
' TODO: Add code to add items to the treeview

Dim sql As String = "SELECT * FROM Kabinet"
Dim cmd As New OleDbCommand(sql, conn)
Dim dr As OleDbDataReader
conn.Open()
dr = cmd.ExecuteReader()

'if this is a rebuild then we don't have to add new columns to
the datatable
If dt.Columns.Count = 0 Then
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("IDParent", GetType(Integer))
End If

If dt.Rows.Count = 0 Then
While dr.Read()
dt.Rows.Add(dr.Item("Id"), dr.Item("foldername"),
dr.Item("parent-Id"))
End While
End If
AddNodes(TreeView.Nodes, dt.Select("ISNULL(IDParent, -1) =
-1"))

dr.Close()
conn.Close()

End Sub
Private Sub AddNodes( _
ByVal Nodes As TreeNodeCollection, ByVal rows As DataRow())

Dim row As DataRow
For Each row In rows
Dim Node As New Node(row)
Nodes.Add(Node)
If Node.Text = "Kabinet" Then
Node.SelectedImageIndex = 2
Node.ImageIndex = 2
End If
'if the user has a subscription on the folder then change
the icon
Dim ID As String = DirectCast(Node.row("ID"), Integer)
If CheckAbonnement(ID) = True Then
Node.SelectedImageIndex = 3
Node.ImageIndex = 3
End If
Dim SubRows = dt.Select("IDParent = " & CInt(row("ID")))
AddNodes(Node.Nodes, SubRows)

Next
End Sub

Marco
 
Ok... Here is a working example.  I have the treeview pointing to an imagelist
with 5 images in it.

Option Strict On
Option Explicit On

Public Class Form1

    MustInherit Class ExpandableNode
        Inherits System.Windows.Forms.TreeNode

        Private _openIndex As Integer
        Private _closeIndex As Integer

        Protected Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
            MyBase.New(text)
            Me.OpenIndex = openIndex
            Me.CloseIndex = closeIndex
            SetCloseIcon()
        End Sub

        Protected Property OpenIndex() As Integer
            Get
                Return _openIndex
            End Get
            Set(ByVal value As Integer)
                _openIndex = value
            End Set
        End Property

        Protected Property CloseIndex() As Integer
            Get
                Return _closeIndex
            End Get
            Set(ByVal value As Integer)
                _closeIndex = value
            End Set
        End Property

        Public Sub SetOpenIcon()
            Me.ImageIndex = OpenIndex
            Me.SelectedImageIndex = OpenIndex
        End Sub

        Public Sub SetCloseIcon()
            Me.ImageIndex = CloseIndex
            Me.SelectedImageIndex = CloseIndex
        End Sub
    End Class

    Class FolderNode
        Inherits ExpandableNode

        Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
            MyBase.New(text, openIndex, closeIndex)
        End Sub
    End Class

    Class EmailFolderNode
        Inherits ExpandableNode

        Public Sub New(ByVal text As String, ByVal openIndex As Integer, ByVal closeIndex As Integer)
            MyBase.New(text, openIndex, closeIndex)
        End Sub
    End Class

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' set default image for nodes
        TreeView1.SelectedImageIndex = 4
        TreeView1.ImageIndex = 4

        ' create a folder node - with a child node
        Dim fn As New FolderNode("A folder node", 1, 0)
        fn.Nodes.Add(New TreeNode("a simple node"))
        TreeView1.Nodes.Add(fn)

        ' create an email folder node - with a simple child node
        Dim en As New EmailFolderNode("A email folder node", 2, 3)
        en.Nodes.Add(New TreeNode("a simple node"))
        TreeView1.Nodes.Add(en)
    End Sub

    Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object,ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1..BeforeExpand
        Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
        If tn IsNot Nothing Then
            tn.SetOpenIcon()
        End If
    End Sub

    Private Sub TreeView1_BeforeCollapse(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeCollapse
        Dim tn As ExpandableNode = TryCast(e.Node, ExpandableNode)
        If tn IsNot Nothing Then
            tn.SetCloseIcon()
        End If
    End Sub
End Class

Tom,

sorry for being a newbie but I don't know how to fit the Form_load
code into my building up the Treeview reading from the database:

Private Sub LoadTree()
' TODO: Add code to add items to the treeview

Dim sql As String = "SELECT * FROM Kabinet"
Dim cmd As New OleDbCommand(sql, conn)
Dim dr As OleDbDataReader
conn.Open()
dr = cmd.ExecuteReader()

'if this is a rebuild then we don't have to add new columns to
the datatable
If dt.Columns.Count = 0 Then
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("IDParent", GetType(Integer))
End If

If dt.Rows.Count = 0 Then
While dr.Read()
dt.Rows.Add(dr.Item("Id"), dr.Item("foldername"),
dr.Item("parent-Id"))
End While
End If
AddNodes(TreeView.Nodes, dt.Select("ISNULL(IDParent, -1) =
-1"))

dr.Close()
conn.Close()

End Sub
Private Sub AddNodes( _
ByVal Nodes As TreeNodeCollection, ByVal rows As DataRow())

Dim row As DataRow
For Each row In rows
Dim Node As New Node(row)
Nodes.Add(Node)
If Node.Text = "Kabinet" Then
Node.SelectedImageIndex = 2
Node.ImageIndex = 2
End If
'if the user has a subscription on the folder then change
the icon
Dim ID As String = DirectCast(Node.row("ID"), Integer)
If CheckAbonnement(ID) = True Then
Node.SelectedImageIndex = 3
Node.ImageIndex = 3
End If
Dim SubRows = dt.Select("IDParent = " & CInt(row("ID")))
AddNodes(Node.Nodes, SubRows)

Next
End Sub

Marco
 
Back
Top