updated example with expanded top node and an optional ignoreList parameter:
try(destroyDialog theRollout)catch()
rollout theRollout "The Rollout" width:300
(
local TreeNodeClass = dotnetclass "System.Windows.Forms.TreeNode"
dotNetControl tv "system.windows.forms.treeView" height:200
fn IsMatch str patternArr =
(
noMatch = true
for p in patternArr while noMatch where matchpattern str pattern:p do noMatch = false
NOT noMatch
)
fn GetDirectoryTree dir ignoreList:undefined =
(
flt = filterstring dir "\\"
dirName = flt[flt.count]
if ignoreList == undefined OR NOT IsMatch dirName ignoreList then
(
t = dotnetobject TreeNodeClass dirName
t.Tag = dir -- assign the full path to the tag property
subDirs = GetDirectories (dir+@"/*")
subNodes = #()
for d in subDirs do
(
sub = GetDirectoryTree d ignoreList:ignoreList
if sub != undefined do append subNodes sub
)
t.Nodes.AddRange subNodes
t
)
else
undefined
)
on theRollout open do
(
n = GetDirectoryTree (getDir #maxroot) ignoreList:#("*maps*")
tv.Nodes.Add n
n.Expand() -- expand the top node
)
)
createDialog theRollout
I owe you a beer Gravey, thanks, hopefully this will be useful for anyone else wanting to do a similar thing.
treeview.Nodes.Clear()
If you really want to know more about dotnet it’s a great investment to spend some time learning how to navigate through the msdn docs!
http://msdn.microsoft.com/en-us/library/system.windows.forms.treenodecollection_methods.aspx
-Johan
I am using Kameleon’s KClasses which really simplifies building the directory tree.
If I have a treeview generated from a directory tree, can I set a specific node to be selected on open?
I would like to write out a user’s last selection to an ini and then retrieve it on open so they can jump back to it when they open the tool again.
I’ve looked at Expand and EnsureVisible methods on MSDN. But these don’t set the node selection. The directory tree may change over time, adding directories mostly. So I assume an index would fail after the structure of the tree changes.
Can I identify a node by its path string? “\server hisFolder hatFolder”
on tvFolders NodeMouseClick sender eb do
(
setINISetting (getdir #userScripts + "\AssetTools.ini") "Browser" "TreeViewDefaultLocation" eb.node.dirName
)
When you are recursing through and building the nodes then just set the one that you want selected as you go.
tv=dotNetObject "treeView"
showProperties tv
tv.SelectedNode=someTreeViewNode
Thanks Paul,
I’m not generating the treeview… Kameleon is doing it for me!
dotnet.loadAssembly "KClasses.dll"
dotnetcontrol tvFolders "KClasses.dnFolders"
tvFolders.ProcessTree(@"\\server\pathToRootFolder")
I don’t think it generates names when it does this. He has added the dirName property but I’m not sure I can use that to set the current node…
I do need to learn the long way around (recursing the folder tree) from your examples. Maybe that is what I need to do after work tonight…
This is what I understood you meant, but I must not have it right.
If you select a node, it saves the node.name to the ini. It just doesn't work to load that string as a node name in tv.SelectedNode
try(destroyDialog theRollout)catch()
rollout theRollout "The Rollout" width:300
(
local TreeNodeClass = dotnetclass "System.Windows.Forms.TreeNode"
dotNetControl tv "system.windows.forms.treeView" height:200
fn IsMatch str patternArr =
(
noMatch = true
for p in patternArr while noMatch where matchpattern str pattern:p do noMatch = false
NOT noMatch
)
fn GetDirectoryTree dir ignoreList:undefined =
(
flt = filterstring dir "\\"
dirName = flt[flt.count]
if ignoreList == undefined OR NOT IsMatch dirName ignoreList then
(
t = dotnetobject TreeNodeClass dirName
t.Tag = dir -- assign the full path to the tag property
t.Name = dir
subDirs = GetDirectories (dir+@"\*")
subNodes = #()
for d in subDirs do
(
sub = GetDirectoryTree d ignoreList:ignoreList
if sub != undefined do append subNodes sub
)
t.Nodes.AddRange subNodes
t
)
else
undefined
)
on theRollout open do
(
n = GetDirectoryTree (getdir #maxroot) ignoreList:#("*cloth*","*drivers*","*pre*")
tv.Nodes.Add n
n.Expand() -- expand the top node
if (hasINISetting (getdir #userScripts + "\TV_Test.ini") "Browser" "TreeViewDefaultLocation") do
(
tv.SelectedNode= (getINISetting (getdir #userScripts + "\TV_Test.ini") "Browser" "TreeViewDefaultLocation")
)
)
on tv NodeMouseClick sender args do
(
setINISetting (getdir #userScripts + "\TV_Test.ini") "Browser" "TreeViewDefaultLocation"args.node.name
clearlistener()
print args.node.name
)
)
createDialog theRollout
setting the tv.SelectedNode to a string is not possible, you need to get the node from the node collection that contains it. Unfortunatly its not enough to just say tv.nodes.Item[“key”] because that will only search the root level TreeNodeCollection. In the code below I am saving the selected node’s FullPath property to the ini file instead of its name and using the GetTreeNodeByFullPath function to search the tree and get the previously selected node. The function returns undefined if any node does not exist along the path which would happen if you changed the root path.
try(destroyDialog theRollout)catch()
rollout theRollout "The Rollout" width:300
(
local TreeNodeClass = dotnetclass "System.Windows.Forms.TreeNode"
dotNetControl tv "system.windows.forms.treeView" height:200
fn IsMatch str patternArr =
(
noMatch = true
for p in patternArr while noMatch where matchpattern str pattern:p do noMatch = false
NOT noMatch
)
fn GetDirectoryTree dir ignoreList:undefined =
(
flt = filterstring dir "\\"
dirName = flt[flt.count]
if ignoreList == undefined OR NOT IsMatch dirName ignoreList then
(
t = dotnetobject TreeNodeClass dirName
t.Tag = dir -- assign the full path to the tag property
subDirs = GetDirectories (dir+@"\*")
subNodes = #()
for d in subDirs do
(
sub = GetDirectoryTree d ignoreList:ignoreList
if sub != undefined do append subNodes sub
)
t.Nodes.AddRange subNodes
t
)
else undefined
)
fn GetTreeNodeByFullPath fullPath =
(
dirNames = filterString fullPath tv.PathSeparator
n = tv
for dirName in dirNames while n != undefined do n = n.Nodes.Item[dirName]
n
)
on theRollout open do
(
tv.HideSelection = false
n = GetDirectoryTree (getdir #maxroot) ignoreList:#("*cloth*","*drivers*","*pre*")
tv.Nodes.Add n
n.Expand() -- expand the top node
fullPath = getINISetting (getdir #userScripts + "\TV_Test.ini") "Browser" "TreeViewDefaultLocation"
if fullPath != undefined do
(
n = GetTreeNodeByFullPath fullPath
if n != undefined do tv.SelectedNode = n
)
)
on tv NodeMouseClick sender args do
(
fullPath = args.node.FullPath
setINISetting (getdir #userScripts + "\TV_Test.ini") "Browser" "TreeViewDefaultLocation" fullPath
)
)
createDialog theRollout
“TreeNodeCollection” has method “Find”
.<System.Windows.Forms.TreeNode[]>Find <System.String>key <System.Boolean>searchAllChildren
to find all nodes in the tree view by key is:
nodes = tv.nodes.Find key on
…and there is no reason to store the full (dir) path in tree node’s name. You always can get it reading tree node’s “FullPath” property. It’s better to store full path’s Hash Value as string.
node.name = (getHashValue <fullpath> 0) as string -- (see mxs help for details)
using the hash value makes all search operations much faster.
also I recommend to convert the full path name to Lower Case and with only Forward Slashes:
str = pathConfig.convertPathToLowerCase str
str = substituteString str "\\" "/"