B4A Library [Class] Treeview Class (Tree and Node)

derez

Expert
Licensed User
Longtime User
I checked with your code in resume and it works. You need only tree2.OpenRoot there.
I don't know why it does not work for you.
Where do you initialize ? where do you add the view ? Does it happan in all devices ?
What happens if you run the demo program ? There is a ResetTree menu, add the tree2.OpenRoot command and see what happens.
The OpenRoot command does the same as clicking the root button (the +). What happens then in your code ?
 
Last edited:

derez

Expert
Licensed User
Longtime User
Version 9 update, to fix large lineheight in high resolution devices.
 

crawler

Member
Licensed User
Longtime User
Hi, I really like your TreeviewC9 and I'm looking at how to merge it with DBRequestManager to RDC an external database (MS SQL Server).
I have RDC set up and working well with a ListView or a ScrollView.
Can you recommend a simple way to do this with your Treeview?
 

derez

Expert
Licensed User
Longtime User
Treeview is just the way of presenting the data.
you should create a sub named GetData and it should provide the data from the DB to the tree for opening a node.
Here is an example from my Family tree application where there are two types of trees - roots and tree, selected by treeflag value.
B4X:
'Set imgtflag 0 for no image, 1 for folder , 2 for file (general), 3 for specific image by imgdir and imgfile, 4 for image by bitmap using da.bmp
Sub GetData(tr As Tree, st As String) 'ignore
Dim k, ColorSet, P_id(2) As Int 'ignore
Dim str, Tag,Text,BtnTag As String 'ignore
k = st
If treeflag Then                                      ' root
    cur = SQL.ExecQuery2("SELECT Fcod, Mcod FROM FTable WHERE No = ?",Array As String(k))
    cur.Position = 0
    P_id(0) = cur.GetInt("Fcod")
    P_id(1) = cur.GetInt("Mcod")
    For j = 0 To 1
        Dim da As Data
        If P_id(j) > 0 Then
            da.Tag = P_id(j)
            If relpnl.Visible AND check_rlist(P_id(j)) Then
                da.ColorSet = 1
            Else
                da.ColorSet = 0
            End If
          
            cur = SQL.ExecQuery2("SELECT Surname, Name, Fcod, Mcod FROM FTable WHERE No = ?",Array As String(P_id(j)))
            cur.Position = 0
            da.Text = cur.GetString("Surname")& " " & cur.GetString("Name")
          
            If cur.GetInt("Fcod") > 0 OR cur.GetInt("Fcod")>0 Then
                da.BtnTag = True
            Else
                da.BtnTag = False
            End If
          
            If File.Exists(File.DirRootExternal & "/Family/jpg",P_id(j) & ".jpg") Then
                da.imgflag = 3
                da.imgdir = File.DirRootExternal & "/Family/jpg"
                da.imgfile = P_id(j) & ".jpg"
            Else
                da.imgflag = 0
            End If
          
            tr.DataList.Add(da)
        End If
    Next
Else                                                    ' tree
    Dim cur1 As Cursor
    Dim kk, scod As Int
    cur = SQL.ExecQuery2("SELECT No,Surname,Name,Scod FROM FTable WHERE Fcod = ? OR Mcod = ?",Array As String(k,k))
    If cur.RowCount > 0 Then
        For i = 0 To cur.RowCount - 1
            Dim da As Data
            cur.Position = i
            kk = cur.GetInt("No")
            scod = cur.GetInt("Scod")
            da.Tag = kk
            If relpnl.Visible AND check_rlist(kk) Then da.ColorSet = 1 Else da.ColorSet = 0
            If scod > 0 Then
                da.Text = cur.GetString("Surname") & " " & cur.GetString("Name") & " + " & Get_Name(scod)
            Else
                da.Text = cur.GetString("Surname") & " " & cur.GetString("Name")
            End If
            cur1 = SQL.ExecQuery2("SELECT No FROM FTable WHERE Fcod = ? OR Mcod = ?",Array As String(kk,kk))
            If cur1.RowCount > 0 Then
                da.BtnTag = True
            Else
                da.BtnTag = False
            End If
          
            If File.Exists(File.DirRootExternal & "/Family/jpg",kk & ".jpg") Then
                da.imgflag = 3
                da.imgdir = File.DirRootExternal & "/Family/jpg"
                da.imgfile = kk & ".jpg"
            Else
                da.imgflag = 0
            End If
            tr.DataList.Add(da)
        Next
    End If
End If
End Sub
 

crawler

Member
Licensed User
Longtime User
Thanks, I'll see what I can do.
Please let me know if you get the Treeview to RDC with your MySQL database.
 

derez

Expert
Licensed User
Longtime User
This application does not work with RDC, but anyway the treeview is just a way to display the data, getting it from/to the RDC is not part of the treeview.
 

Troberg

Well-Known Member
Licensed User
Longtime User
Is it possible to make a "root-less" tree (or, if you prefer, a multi-root tree)?

Say, for example, that I wan't to make a media list, with the levels being artist, album and title, such as:

The Sisters of Mercy
+ Some girls wander by mistake
++ Temple of Love
++ Floorshow
+ Floodland
++ Lucretia
Rammstein
+ Herzeleid
++ Seemann
+ Mutter
++ Ich Will
++ Sonne

In this example, both The Sisters of Mercy and Rammstein would be at the root level.
 

Troberg

Well-Known Member
Licensed User
Longtime User
Oh, by the way, another thing that would be incredibly handy is a way to add a node with a path, and it takes care of creating intermediary nodes as needed automatically.

In my example above, I would do something like (now, I'm ignoring some bits just to keep it clear):

item.Path="The Sisters of Mercy/Some girls wander by mistake/Temple of Love"
tree.AddByPath(item)

This would then add item as a node, and automatically create the nodes "The Sisters of Mercy" and "Some girls wander by mistake" at the correct position if they don't already exist.

It's not something that's always useful (for example, when listing a file system, it's not that useful), but in other cases, it's immensely practical.

I've made my own subclassed treeview for VB with (among other things) this method, and it really helps simplify and clean up usage.
 

derez

Expert
Licensed User
Longtime User
Is it possible to make a "root-less" tree (or, if you prefer, a multi-root tree)?
A tree by definition must have a root. In your example each album name is the tree root and you need trees as the number of albums.
a way to add a node with a path, and it takes care of creating intermediary nodes as needed automatically.
The tree as is works like this, with the understanding that someone (you ! ) has to give it the path. In directory/file tree the logic is by listing files in directory which is embedd in the language. For your case you need to create the database so the creation of a node can look for the data ("path" ) somewhere.
The sub that should take care of this data is "GetData" which you have to put in the module that calls the tree.
 

Troberg

Well-Known Member
Licensed User
Longtime User
Yep, I've looked a bit more now, andI realize I've misunderstood a couple of things.

As it is, it does not look like it's the right component for me, as I don't want to fill it gradually as nodes are expanded, I just want to stuff it all in there. I get all my data in one operation, and it would require me to build up some searchable backend for caching my data. Too much work, I'll build another solution.

Thanks anyway, it's a neat solution, if one has the right needs.
 

Bernhard Svavarsson

Member
Licensed User
Longtime User



Interesting - Not sure what is or where is 'Treeflag' defined ?

Regards

Bernhard
 

derez

Expert
Licensed User
Longtime User
Not sure what is or where is 'Treeflag' defined ?
Treeflag is a global boolean, made false or true by the user who wants to see, for the presented person, either the roots tree or the offsprings tree.
To clarify, it is not part of the class but of the specific application.
 

Bernhard Svavarsson

Member
Licensed User
Longtime User
Treeflag is a global boolean, made false or true by the user who wants to see, for the presented person, either the roots tree or the offsprings tree.
To clarify, it is not part of the class but of the specific application.

Thanks - yes of course it's not part of the class

Regards

Bernhard
 

derez

Expert
Licensed User
Longtime User
In post #44 above I give an example of two trees which are selected by the boolean treeflag. In your data base these are the two tables.
You should take a decision in sub GetData - if the node clicked is the root(inventory) you have to add the two table roots as nodes to inventory, otherwise open the node clicked from the required table (a or b). How to tell which table to use ? depends on your data.
As you see, GetData is not actually part of the tree, it is "just" providing the data to the opened nodes.
 

ToolboxZX

Member
Licensed User
Longtime User
derez,

Is it possible to add code to change the image of the node next to the + / - symbol when a user expands or collapses a tree? I see in the code how to change what images are added as the nodes are created, and also how to change out the actual + and - images for whatever I want in the code. But it is not clear how to change the other image (next to the plus or minus). Thanks!
 

derez

Expert
Licensed User
Longtime User
Node.initialize includes an img parameter, so you have to pass it from the main to tree class in the da type.
 

ToolboxZX

Member
Licensed User
Longtime User
Derez thanks for the reply Can you give me an example, or show the section of code this would be in? I having trouble visualizing it What I am after basically is to be able to change the icon of the folder from closed to open when you expand or collapse that section of the tree (think Windows File manager).
 

derez

Expert
Licensed User
Longtime User
What I am after basically is to be able to change the icon of the folder from closed to open when you expand or collapse that section of the tree (think Windows File manager).
I don't understand. The feature you describe is exactly what the first icon (+/-) does !
Please look at the example: in Node module sub btn_click calls node_open or node_close in Tree module, and switch the icons +-.
After that, node_open calls the main module to get the data about the node's content and node_close removes the node's content.
 
Last edited:

ToolboxZX

Member
Licensed User
Longtime User
Sorry, I used a poor example (Windows File Manager). Yes, the first icon (+/-) does change. In addition to that, I am trying to change the other icon, on the same line as the +/- icon, associated with the node. Here are some images to clarify
 

Attachments

  • closed folder example2.png
    5 KB · Views: 186
  • open folder example2.png
    6.7 KB · Views: 175
  • open folder example3.png
    9.8 KB · Views: 177

derez

Expert
Licensed User
Longtime User
change fileimg and folderimg to be the images in your example, instead of the attached images to my example:
B4X:
fileimg.Initialize(File.DirAssets,"file.png")
folderimg.Initialize(File.DirAssets,"folder2.png")
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…