Jump to content
Sign in to follow this  
mattw112

Treeview Logic

Recommended Posts

mattw112

Never done one of these before and trying to wrap my head around the logic.

So I've read the help guide, know about the two different ways to create a treeview, tried finding some relevant examples on the forums ... I created a demo and that was pretty easy when you have just a few items hard coded into the code.

My situation is this:

I have a Class in WMI that has two main properties. "Parent" and "Child". There are over 500 instances of these. but to simplify look below:

post-3866-12780174117492_thumb.jpg

ok, so you see that it isn't really sorted from top to bottom. Relationships can be defined anywhere.

Also all items can only be a child to one parent. But there could be 0 to X number of Children to a parent.

I'd like to have this create an expanding treeview showing all these relationships.

So just using psudeo code (or describing in english) how does one go about doing a loop that figures out the parent child relationships and then is able to create treeview items form that information?

I'm thinking since "ROOT" is the very root that the top level can be connected to then I'd start there. maybe something like:

$TopItem = GUICtrlCreateTreeViewItem("ROOT", $TreeView1)

Read CHILD column

For $member in $members

If parent name = ROOT then

$member = GUICtrlCreateTreeViewItem($member, $TopItem)

Next

But after that I'm a little lost on how it works. How would I be able to go through and find the relationships especially when some parents to childs might be listed before that parent has been defined?

Thanks,

Terry

Share this post


Link to post
Share on other sites
PsaltyDS

Here's one way to do it:

#include <GuiConstantsEx.au3>
#include <Array.au3>
#include <GuiTreeView.au3>

Global $hGUI, $hTV, $idButton

; [0] = Parent, [1] = Child
Global $aTreeData[9][2] = [ _
        ["Root", "Child1"], _
        ["Subchild5", "Subchild6"], _
        ["child2", "Subchild3"], _
        ["root", "child2"], _
        ["Child1", "Subchild2"], _
        ["root", "child3"], _
        ["Child1", "Subchild1"], _
        ["child3", "Subchild4"], _
        ["Subchild2", "Subchild5"]]

Global $aTreeAdd[5][2] = [ _
        ["Child4", "Subchild7"], _
        ["Subchild5", "Subchild10"], _
        ["Child2", "Subchild8"], _
        ["Root", "Child4"], _
        ["Child1", "Subchild9"]]

$hGUI = GUICreate("Test", 400, 400)
$hTV = _GUICtrlTreeView_Create($hGUI, 20, 20, 360, 310)
_Add_TV_Data($aTreeData)
$idButton = GUICtrlCreateButton("Add", 150, 350, 100, 30)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $idButton
            _Add_TV_Data($aTreeAdd)
            ControlDisable($hGUI, "", $idButton)
    EndSwitch
WEnd

Func _Add_TV_Data($aTVData)
    Local $f_Change, $hNew, $hParent

    Do
        $f_Change = False
        For $n = UBound($aTVData) - 1 To 0 Step -1
            If $aTVData[$n][0] = "Root" Then
                $f_Change = True
                $hNew = _GUICtrlTreeView_Add($hTV, 0, $aTVData[$n][1])
                _ArrayDelete($aTVData, $n)
            Else
                $hParent = _GUICtrlTreeView_FindItem($hTV, $aTVData[$n][0])
                If $hParent Then
                    $f_Change = True
                    $hNew = _GUICtrlTreeView_AddChild($hTV, $hParent, $aTVData[$n][1])
                    _ArrayDelete($aTVData, $n)
                EndIf
            EndIf
        Next
    Until $f_Change = False
    _GUICtrlTreeView_Expand($hTV)

    $hDebug = _GUICtrlTreeView_FindItem($hTV, "subchild10")
    ConsoleWrite("Test = " & $hDebug & @LF)
EndFunc   ;==>_Add_TV_Data

Here a 2D array is used to input the data. This runs an iterative loop that adds the items, deleting them as they are added. Items that don't have a valid parent are simply skipped, and they get caught next time around.

The loop continues until there are no more entries in the array, or it goes though the remaining items without making any changes (indicates invalid parent text).

:blink:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
mattw112

Thanks,

I've been trying to get this working by populating the array myself.

Can you tell me what is the difference between the way you have the array manually set shown above

Global $aTreeData[9][2] = [ _
        ["Root", "Child1"], _
        ["Subchild5", "Subchild6"], _
        ["child2", "Subchild3"], _
        ["root", "child2"], _
        ["Child1", "Subchild2"], _
        ["root", "child3"], _
        ["Child1", "Subchild1"], _
        ["child3", "Subchild4"], _
        ["Subchild2", "Subchild5"]]

And

Global $aCol[1][2]
For $Member in $Members
    $Parent = $Member.ParentID
    $Child = $Member.ChildID

    _Array2D_Add($aCol, $Parent & "|" & $Child, Default)
Next

For some reason when I try to populate the array from the WMI store it doesn't work (Nothing appears in Treeview). But it works if I use your manual entry.

When I do a:

_Array2D_Display($aCol, "Whole 2D-array")

on your array and my array they both look the same pretty much except mine has a ton more rows.

NOTE: yes I know the array name is different, I've changed your code to accept that.

Thanks,

Terry

Edited by mattw112

Share this post


Link to post
Share on other sites
PsaltyDS

Couldn't tell you because I don't have _Array2D_Add(). Can you post that function?

:blink:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
mattw112

Couldn't tell you because I don't have _Array2D_Add(). Can you post that function?

:blink:

Attached. I had to make a small modification from the original authors since it is a couple years old... basically just changed all _StringSplit's to StingSplit.

Terry

PS - Originally I got it here:

Original

Seems good for working with 2D arrays not sure why it was abandoned 2 years ago.

Array2D.au3

Share this post


Link to post
Share on other sites
PsaltyDS

Egad... talk about over complicated! ;)

Since you are gathering this data from a collection object, does it have a .count property? If so, I would dump that entire Array2D UDF and just do something like this:

Global $aCol[1][2]

; ... Do whatever to get $Members collection

$iIndex = UBound($aCol)
$iCount = $Members.count
ReDim $aCol[$iIndex + $iCount][2]
For $Member in $Members
    $aCol[$iIndex][0] = $Member.ParentID
    $aCol[$iIndex][1] = $Member.ChildID
    $iIndex += 1
Next

:blink:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
mattw112

Thanks! I didn't have a count method to choose from, so instead just iterated through them and got a count ahead of time and used that number.

Anyway it is working now! And I think I understand. Although not sure I understand why the array2D.au3 wasn't working the array seems to look exactly the same as now?

Thanks,

Terry

Edited by mattw112

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×