Drawing a square (or circles) before each item of a treeview

  • Thread starter Thread starter pamelafluente
  • Start date Start date
P

pamelafluente

Hi

I have some instances of a class:

Class Myobject
Public Color As Color
Public Label As String
End Class

I need to show these instances on a treeview (which has checked boxes)
and I would
like to show the color of each instance as a little colored square
(or circle) before the box (and label) of each item.

Can anyone tell me how do I do that? Thank you.


pam
 
Him Pam,

I looked into trying to extend the treeview's node class and couldn't find a
way to do it. If there is one, I'd also like to know how.
 
For today, I can solve your problem in a very simple way, if you accept
the colors to appear after the check boxes. Which is anyway useful. The
final effect is quite nice. Here is a complete source code ....

For tomorrow, if you have extra money and extra needs you might
consider to take a look at jeff's Tlist
www.Bennet-Tec.com/btproducts/TList/TList.htm

Suggestions for improvements are very welcome
[could have generalized using interfaces, but I wanted to keep it
simple just to illustrate the general idea ... ]

Tom
"Datatime Free" Project

CUSTOM DRAW ITEMS in a TreeView
Assume Form1 with TreeView1
'----------------------------------------------------------------

Public Class Form1

Class YourObject
Public Text As String
Public Checked As Boolean
Public Color As Color
End Class

Private DifferentBrushes As New Hashtable 'to cache the brushes
(for some efficiency)
Dim Reduction As Integer = 2
'use even number (expresses the reduction in pixels of the colored
square wrt to the item height)
'Reduction = 2 make it equal to the check box
'For other values the icon is centered wrt the check box

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

'Test Objects ---------------------------------------------
Dim YourObject1 As New YourObject
With YourObject1
.Text = "hi"
.Checked = True
.Color = Color.RoyalBlue
End With

Dim YourObject2 As New YourObject
With YourObject2
.Text = "Here is a simple example"
.Checked = False
.Color = Color.Orchid
End With

Dim YourObject3 As New YourObject
With YourObject3
.Text = "by Tommaso [Datatime free project ;)]"
.Checked = True
.Color = Color.Green
End With

Dim YourObject4 As New YourObject
With YourObject4
.Text = "http://cam70.sta.uniroma1.it/TechnicalPreview/"
.Checked = False
.Color = Color.Olive
End With

Dim YourObjects() As YourObject = New YourObject()
{YourObject1, YourObject2, YourObject3, YourObject4}


'--------------------- GENERAL PART
-----------------------------------
With Me.TreeView1
.DrawMode = TreeViewDrawMode.OwnerDrawText
.ShowLines = False
.FullRowSelect = True
.CheckBoxes = True
.Width = 300
End With

Dim Nodes As New ArrayList
DifferentBrushes.Clear()
For Each YourObject As YourObject In YourObjects
Dim TreeNode As New TreeNode()
With TreeNode
.Tag = YourObject
.Text = YourObject.Text
.Checked = YourObject.Checked
End With
If YourObject.Color = Color.Empty Then YourObject.Color =
Me.TreeView1.BackColor
If Not DifferentBrushes.ContainsKey(YourObject.Color.Name)
Then
DifferentBrushes.Add(YourObject.Color.Name, New
SolidBrush(YourObject.Color))
End If
Nodes.Add(TreeNode)
Next YourObject

Dim TreeNodes(Nodes.Count - 1) As TreeNode
Nodes.CopyTo(TreeNodes)
Me.TreeView1.Nodes.Clear()
Me.TreeView1.Nodes.AddRange(TreeNodes)

End Sub

Private Sub TreeView1_DrawNode(ByVal sender As Object, ByVal e As
System.Windows.Forms.DrawTreeNodeEventArgs) Handles TreeView1.DrawNode

Dim YourObject As YourObject = Nothing
If TypeOf e.Node.Tag Is YourObject Then
YourObject = DirectCast(e.Node.Tag, YourObject)
Else
Exit Sub
End If

Dim Side As Integer = e.Bounds.Height - Reduction - 3 '(the
check box border compensation)
Dim IconY As Integer = e.Bounds.Y + Reduction \ 2 + 2
Dim Offset As Integer = 2

Dim X As Integer = e.Bounds.X + Offset
Dim Brush As Brush =
DirectCast(DifferentBrushes(YourObject.Color.Name), Brush)

''Colored icon to show the associate color (change the shape
according to your taste)

'Rectangula ICON
e.Graphics.FillRectangle(Brush, New Rectangle(X, IconY, Side,
Side))

''CIRCULAR ICON
'e.Graphics.FillEllipse(Brush, New Rectangle(X, IconY, Side,
Side))

'TreeNode text
Dim f As Font = e.Node.NodeFont
If f Is Nothing Then f = e.Node.TreeView.Font
e.Graphics.DrawString(e.Node.Text, f, Brush, X + Side,
e.Bounds.Y)

End Sub

End Class
 
That is cool!

I figured you would somehow inherit from a treenode class or something.
But, alas, it is the same principal as owner drawn listboxes and menus.

For today, I can solve your problem in a very simple way, if you accept
the colors to appear after the check boxes. Which is anyway useful. The
final effect is quite nice. Here is a complete source code ....

For tomorrow, if you have extra money and extra needs you might
consider to take a look at jeff's Tlist
www.Bennet-Tec.com/btproducts/TList/TList.htm

Suggestions for improvements are very welcome
[could have generalized using interfaces, but I wanted to keep it
simple just to illustrate the general idea ... ]

Tom
"Datatime Free" Project

CUSTOM DRAW ITEMS in a TreeView
Assume Form1 with TreeView1
'----------------------------------------------------------------

Public Class Form1

Class YourObject
Public Text As String
Public Checked As Boolean
Public Color As Color
End Class

Private DifferentBrushes As New Hashtable 'to cache the brushes
(for some efficiency)
Dim Reduction As Integer = 2
'use even number (expresses the reduction in pixels of the colored
square wrt to the item height)
'Reduction = 2 make it equal to the check box
'For other values the icon is centered wrt the check box

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

'Test Objects ---------------------------------------------
Dim YourObject1 As New YourObject
With YourObject1
.Text = "hi"
.Checked = True
.Color = Color.RoyalBlue
End With

Dim YourObject2 As New YourObject
With YourObject2
.Text = "Here is a simple example"
.Checked = False
.Color = Color.Orchid
End With

Dim YourObject3 As New YourObject
With YourObject3
.Text = "by Tommaso [Datatime free project ;)]"
.Checked = True
.Color = Color.Green
End With

Dim YourObject4 As New YourObject
With YourObject4
.Text = "http://cam70.sta.uniroma1.it/TechnicalPreview/"
.Checked = False
.Color = Color.Olive
End With

Dim YourObjects() As YourObject = New YourObject()
{YourObject1, YourObject2, YourObject3, YourObject4}


'--------------------- GENERAL PART
-----------------------------------
With Me.TreeView1
.DrawMode = TreeViewDrawMode.OwnerDrawText
.ShowLines = False
.FullRowSelect = True
.CheckBoxes = True
.Width = 300
End With

Dim Nodes As New ArrayList
DifferentBrushes.Clear()
For Each YourObject As YourObject In YourObjects
Dim TreeNode As New TreeNode()
With TreeNode
.Tag = YourObject
.Text = YourObject.Text
.Checked = YourObject.Checked
End With
If YourObject.Color = Color.Empty Then YourObject.Color =
Me.TreeView1.BackColor
If Not DifferentBrushes.ContainsKey(YourObject.Color.Name)
Then
DifferentBrushes.Add(YourObject.Color.Name, New
SolidBrush(YourObject.Color))
End If
Nodes.Add(TreeNode)
Next YourObject

Dim TreeNodes(Nodes.Count - 1) As TreeNode
Nodes.CopyTo(TreeNodes)
Me.TreeView1.Nodes.Clear()
Me.TreeView1.Nodes.AddRange(TreeNodes)

End Sub

Private Sub TreeView1_DrawNode(ByVal sender As Object, ByVal e As
System.Windows.Forms.DrawTreeNodeEventArgs) Handles TreeView1.DrawNode

Dim YourObject As YourObject = Nothing
If TypeOf e.Node.Tag Is YourObject Then
YourObject = DirectCast(e.Node.Tag, YourObject)
Else
Exit Sub
End If

Dim Side As Integer = e.Bounds.Height - Reduction - 3 '(the
check box border compensation)
Dim IconY As Integer = e.Bounds.Y + Reduction \ 2 + 2
Dim Offset As Integer = 2

Dim X As Integer = e.Bounds.X + Offset
Dim Brush As Brush =
DirectCast(DifferentBrushes(YourObject.Color.Name), Brush)

''Colored icon to show the associate color (change the shape
according to your taste)

'Rectangula ICON
e.Graphics.FillRectangle(Brush, New Rectangle(X, IconY, Side,
Side))

''CIRCULAR ICON
'e.Graphics.FillEllipse(Brush, New Rectangle(X, IconY, Side,
Side))

'TreeNode text
Dim f As Font = e.Node.NodeFont
If f Is Nothing Then f = e.Node.TreeView.Font
e.Graphics.DrawString(e.Node.Text, f, Brush, X + Side,
e.Bounds.Y)

End Sub

End Class
 
Back
Top