|
|
|||||||
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 |
||||||||
|
|
|||||||
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 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 |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
I think something like that .Tag may be the only way. I cannot seem to find any other properties that help. |
||||||||
|
|
|||||||
now now... wait just a minute, let me take a lookie :P |
||||||||
|
|
|||||||
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 |
||||||||
|
|
|||||||
checkstate would be a nice addition but couldn't get it to work. I guess it's not supported on classic. |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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 |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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)) |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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... |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
blaah. harder than expected. untagging to infinite levels doesn't work yet... |
||||||||
|
|
|||||||
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 |
||||||||
|
|
|||||||
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 |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
so... you decided to stay home for easter and instead take a week of work right after? :P |
||||||||
|
|
|||||||
nah.. Easter weekend was in Austria .. the week after Easter I was on Mallorca for a bit of cycling 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. |
||||||||
|
|
|||||||
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) |
||||||||
|
|
|||||||
load tree from xml or something... something shawn would need to consider. should make it faster versus calling com thousands of times... |
||||||||
|
|
|||||||
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:
|
||||||||
|
|
|||||||
enable processing of events while the form is moving? isn't that an event of it's own? |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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. |
||||||||
|
|
|||||||
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? |
||||||||
|
|
|||||||
could. if someone can get a hold of him |
||||||||
|
|
|||||||
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. |