JochenAdministrator
(KiX Supporter)
2012-04-10 03:43 PM
Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Guys,

again having trouble with my current project.
Can't tell when looping through a TreeViews Node Collection if the current Node has child nodes in the next level (my TreeView will have 3 levels of Nodes, all checkable)

here's what I tried (one of Shawns samples adapted a bit to simulate more than one level of Nodes, totally unstylish, what I can't find is in the comment in the only function of the script)

 Code:
Break On
global $l1, $l2
$= setoption("NoVarsInStrings","ON")
$System = CreateObject("Kixtart.System")

$f = split(readprofilestring(@scriptdir + "\Form.ini", "Form", ""),chr(10))

$Form = $System.Form()
$Form.Size = 640,480
$Form.Center()

$Form.ToolGroupBox = $Form.GroupBox()
$Form.ToolGroupBox.Height = 30
$Form.ToolGroupBox.Dock = 1

$Form.StatusGroupBox = $Form.GroupBox()
$Form.StatusGroupBox.Height = 20
$Form.StatusGroupBox.Dock = 2

$Form.TreeView1 = $Form.Controls.Add("TreeView")
$Form.TreeView1.Width = $Form.ClientWidth / 4
$Form.TreeView1.Dock = 3
$Form.TreeView1.ShowLines			= 1
$Form.TreeView1.ShowPlusMinus		= 1
$Form.TreeView1.ShowRootLines		= 1
$Form.TreeView1.CheckBoxes			= 1
$Form.TreeView1.OnClick             = "treeView_Click()"
$Form.TreeView1.OnAfterSelect		= "treeView_Click()"

$Form.Splitter1 = $Form.Splitter()
$Form.Splitter1.Dock = 3

$Form.TextBox1 = $Form.TextBox()
$Form.TextBox1.Multiline = 1
$Form.TextBox1.Dock = 5

for each $e in $f
	if $e
		$l1 = $Form.TreeView1.Nodes.Add($e)
		$l2 = $Form.TreeView1.Nodes(ascan($f,$e)).Nodes.Add($e+" - " + readprofilestring(@scriptdir + "\Form.ini", "Form", $e))
	endif
next

$Form.Show
While $Form.Visible
 $=Execute($System.Application.DoEvents)
Loop

Exit 1

function treeView_Click()
	dim $checkedNodes
	for $i = 0 to $Form.Treeview1.Nodes.Count - 1
		if $Form.Treeview1.Nodes($i).checked
			$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).FullPath + @crlf
		endif
		; here would go something like
		; if $Form.Treeview1.Nodes($i).HasChild ..
	next
	if $checkedNodes
		$Form.TextBox1.Text = $checkedNodes
	endif
endfunction


attached is the file I used to get input for the TreeView..

As you will see only the first level of checked Nodes will get displayed right of the splitter \:\(



JochenAdministrator
(KiX Supporter)
2012-04-10 03:53 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

More Background:

as my final treeView will have 3 levels I want that if one checks a Node all child Nodes will get checked as well .. which I fear I will have to do programmatically \:D

oh, and leaving out the condition in the update of TextBox will make it even clearer:

 Code:
function treeView_Click()
	dim $checkedNodes
	for $i = 0 to $Form.Treeview1.Nodes.Count - 1
		if $Form.Treeview1.Nodes($i).checked
			$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).FullPath + @crlf
		endif
		; here would go something like
		; if $Form.Treeview1.Nodes($i).HasChild ..
	next
	$Form.TextBox1.Text = $checkedNodes
endfunction


JochenAdministrator
(KiX Supporter)
2012-04-10 07:26 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

possible workaround could be the .Tag property in combination with the .GetNodeAT(X, Y) method (undocumented ?!!?)

But on the other side, I may have up to 5000+ Nodes in 3 levels of Nodes. Could be a performance nightmare.


ShaneEP
(MM club member)
2012-04-11 04:21 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

I think something like that .Tag may be the only way. I cannot seem to find any other properties that help.

LonkeroAdministrator
(KiX Master Guru)
2012-04-11 04:34 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

now now... wait just a minute, let me take a lookie :P

LonkeroAdministrator
(KiX Master Guru)
2012-04-11 04:40 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

there you go:
 Code:
function treeView_Click()
	dim $checkedNodes, $i, $is
	for $i = 0 to $Form.Treeview1.Nodes.Count - 1
		if $Form.Treeview1.Nodes($i).checked
			$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).FullPath + @crlf
		endif
		for $is = 0 to $Form.Treeview1.Nodes($i).Nodes.Count - 1
			if $Form.Treeview1.Nodes($i).Nodes($is).checked
				$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).Nodes($is).FullPath + @crlf
			endif
		next
	next
	if $checkedNodes
		$Form.TextBox1.Text = $checkedNodes
	endif
endfunction


LonkeroAdministrator
(KiX Master Guru)
2012-04-11 04:55 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

checkstate would be a nice addition but couldn't get it to work. I guess it's not supported on classic.

ShaneEP
(MM club member)
2012-04-11 07:32 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

 Quote:
I want that if one checks a Node all child Nodes will get checked as well

Maybe I'm missing the real problem, but this still does not work with your new UDF. At least not on my system here.


ShaneEP
(MM club member)
2012-04-11 07:36 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Maybe something like this?...
 Code:
function treeView_Click()
	dim $checkedNodes, $i, $is
	for $i = 0 to $Form.Treeview1.Nodes.Count - 1
		if $Form.Treeview1.Nodes($i).checked
			$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).FullPath + @crlf
		endif
		for $is = 0 to $Form.Treeview1.Nodes($i).Nodes.Count - 1
			if $Form.Treeview1.Nodes($i).checked
				$Form.Treeview1.Nodes($i).Nodes($is).checked = 1
				$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).Nodes($is).FullPath + @crlf
			else
				$Form.Treeview1.Nodes($i).Nodes($is).checked = 0
			endif
		next
	next
	if $checkedNodes
		$Form.TextBox1.Text = $checkedNodes
	endif
endfunction


LonkeroAdministrator
(KiX Master Guru)
2012-04-11 11:32 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

oh, I missed that reply comment...

but...
there is a minor issue with your approach.
if someone checks a box on third level and the upper level is not checked, his check will be wiped out.
this is also why I wanted to have the tri-state checkbox action in there.

maybe something like the following.
a) if all childnodes checked, check also the parent
b) if parent is de-checked, uncheck all children
c) if parent is checked, check all children

note that the example ini doesn't really work for testing anymore as we only have 1 child in every node.
 Code:
found a bug. the corrected code in next post.




LonkeroAdministrator
(KiX Master Guru)
2012-04-11 11:37 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

the above code corrected here:
 Code:
function treeView_Click()
	dim $checkedNodes, $i, $is
	for $i = 0 to $Form.Treeview1.Nodes.Count - 1
		if $Form.Treeview1.Nodes($i).checked
			$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).FullPath + @crlf
			for $is = 0 to $Form.Treeview1.Nodes($i).Nodes.Count - 1
				$Form.Treeview1.Nodes($i).Nodes($is).checked = 1
			next
			$Form.Treeview1.Nodes($i).tag = 1
		else
			if $Form.Treeview1.Nodes($i).tag = 1
				for $is = 0 to $Form.Treeview1.Nodes($i).Nodes.Count - 1
					$Form.Treeview1.Nodes($i).Nodes($is).checked = 0
				next
				$Form.Treeview1.Nodes($i).tag = 0
			endif
		endif
		dim $nc
		$nc=1
		for $is = 0 to $Form.Treeview1.Nodes($i).Nodes.Count - 1
			if $Form.Treeview1.Nodes($i).Nodes($is).checked
				$checkedNodes = $checkedNodes + $Form.Treeview1.Nodes($i).Nodes($is).FullPath + @crlf
			else
				$nc=0
			endif
		next
		if $nc=1 and not $Form.Treeview1.Nodes($i).checked
			$Form.Treeview1.Nodes($i).checked = 1
			$Form.Treeview1.Nodes($i).tag = 1
		endif
	next
	if $checkedNodes
		$Form.TextBox1.Text = $checkedNodes
	endif
endfunction


the missing line caused unchecking a parent impossible in situation when it was checked because children all were checked. now it seems to work as expected.


ShaneEP
(MM club member)
2012-04-12 01:35 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Still seems a little out of whack. I added this line to the form code to get a 3rd level.
 Code:
		$l3 = $l2.Nodes.Add($e+" - " + readprofilestring(@scriptdir + "\Form.ini", "Form", $e))


ShaneEP
(MM club member)
2012-04-12 01:36 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Clicking the parent only checks the 2nd level, not the third. Also clicking just the 2nd level will check the parent and itself but not the 3rd.

LonkeroAdministrator
(KiX Master Guru)
2012-04-12 02:15 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

ok, now as we have a deeper construct, if this is what is he wanting, the we need to modify the code. I thought his required level was demonstrated by his post.
brb...


LonkeroAdministrator
(KiX Master Guru)
2012-04-12 03:07 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

this is weird.
not really sure how it happens but sometimes all checkboxes get checked without any of them actually being checked (just clicking on the treeview makes it happen). don't make no sense.


LonkeroAdministrator
(KiX Master Guru)
2012-04-12 03:51 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

blaah. harder than expected.
untagging to infinite levels doesn't work yet...


LonkeroAdministrator
(KiX Master Guru)
2012-04-12 04:06 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

here you go my friend.
 Code:
function treeView_Click()
		$trash = CheckedNodes($Form.Treeview1)
		$Form.TextBox1.Text = CheckedNodes($Form.Treeview1)
endfunction

Function CheckedNodes($parent)
	dim $i, $nc, $no
	for $i = 0 to $parent.Nodes.Count - 1
		if $parent.tag=1 and not $parent.checked
			$parent.Nodes($i).checked = 0
		endif
		if $parent.checked and $parent.tag<>1
			$parent.tag = 1
			$parent.Nodes($i).checked = 1
		endif
		$checkedNodes=$checkedNodes+CheckedNodes($parent.Nodes($i))
		if $parent.Nodes($i).checked
			$checkedNodes = $checkedNodes + $parent.Nodes($i).FullPath + @crlf
			$no=$no+1
			$nc=$nc+1
		else
			$no=$no+1
		endif
	next
	if $nc=$no and $no>0 and not $parent.checked and $parent.tag<>1
		$parent.checked = 1
		$parent.tag = 1
	else
		if $nc=0 and $no>0 and $parent.checked and $parent.tag=1
			$parent.checked = 0
			$parent.tag = 0
		endif
	endif
	if $parent.tag=1 and not $parent.checked
		$parent.tag=0
	endif
EndFunction


JochenAdministrator
(KiX Supporter)
2012-04-13 06:47 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Wow guys,

always a pleasure to post my questions here, as I know they will be answered or there is no answer \:\)

Will dig into what you both have done and report back what I took with me.
Probably in the week after next because my plane is due to start anytime soon now and I don't know if they already invented free WiFi on Mallorca since last year this time ;\)


JochenAdministrator
(KiX Supporter)
2012-04-13 06:51 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Had to try, could not resist!

Excellent! Now, let's see what this does to the performance with 5100+ Nodes

See you next week or the week after that.


LonkeroAdministrator
(KiX Master Guru)
2012-04-13 04:10 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

5100+?
it might have some delays :p

for that purpose, there is actually "easier" way to accomplish this :p

but, let us know, if it is worth coding a faster solution.


LonkeroAdministrator
(KiX Master Guru)
2012-04-13 07:10 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

so... you decided to stay home for easter and instead take a week of work right after? :P

JochenAdministrator
(KiX Supporter)
2012-04-29 07:46 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

nah.. Easter weekend was in Austria .. the week after Easter I was on Mallorca for a bit of cycling \:D

Anyway.. here's what came out:

I settled with a combination of GetNodeAT(), Tags and Node.Parent .. Now I control the selection of 3 levels of nodes with many nodes below level1 and 2 flawlessly .. The icing of that cake would be a Threestate property for the treeview, but hey, it looks very good without either..

Thanx again for your effort, both of you.


JochenAdministrator
(KiX Supporter)
2012-04-29 07:49 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Oh yeah, forgot .. If Shawn should read this:

I would not only like the ThreeState property for TreeViews, I'd be pleased even more when there was an implementation of .Hide and .Show single Nodes (At the moment it takes almost 20 seconds to build the Tree, and filters are a nono, when I have to destroy and rebuild it)


LonkeroAdministrator
(KiX Master Guru)
2012-04-29 09:20 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

load tree from xml or something...
something shawn would need to consider.
should make it faster versus calling com thousands of times...


It_took_my_meds
(Hey THIS is FUN)
2012-04-30 01:53 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

I would dearly love it if we could get Shawn to do a maintenance release of KiXforms where the current bugs could be addressed and some highly desirable properties, methods, and events could be added.

Perhaps we could put together a reasonable list that hopefully wouldn't take him much time to fix/add and those that still keep in touch with him could ask him directly?

Off the top of my head, my wish list is:
  • Fixing the form disposal bug.
  • Inserting and removing of menu items.
  • More gridview and listview events. (I would like to be able to detect sorts and enable reordering of columns by dragging headers)
  • Enable processing of events whilst the form is moving.



LonkeroAdministrator
(KiX Master Guru)
2012-04-30 02:05 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

enable processing of events while the form is moving?
isn't that an event of it's own?


It_took_my_meds
(Hey THIS is FUN)
2012-04-30 02:09 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

The event queue is stopped whilst the form is moving. The form move message (and any other messages such as a timer message for example) only comes through once the user has taken their finger off the mouse button. It is as though KiXforms freezes during form moves.

It_took_my_meds
(Hey THIS is FUN)
2012-04-30 02:17 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

I should also mention that erroneous form move messages do come through, even when the move is not moving. The same goes for OnMouseMove events on gridviews. Lots of messages come through even when the mouse isn't moving.

LonkeroAdministrator
(KiX Master Guru)
2012-04-30 03:27 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

oh. might the be the fact that moving the form is internal windows thing. takes precedence.
bet there is someway to overcome that. some kind of canceling of the event.


It_took_my_meds
(Hey THIS is FUN)
2012-04-30 06:36 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

Please let me know if you find a way to overcome it. Anyway, what do you think about getting a list together? Do you think we could get Shawn to do an update?

LonkeroAdministrator
(KiX Master Guru)
2012-04-30 06:58 AM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

could. if someone can get a hold of him \:\)

ShaneEP
(MM club member)
2012-04-30 04:40 PM
Re: Kf.Classic: How do I determine if TreeNode has Child Nodes ?l

The most annoying thing I've run into is not being able to use base64 images for form icons. It's already capable for images on a form, so I wouldn't think it would take much to make the same functionality available for icons.