James:
James Bott wrote:Have you tried oTree:aItems[n]:expand()?
Indeed. I was looking for an efficient way to walk through the branches and either expand or collapse all branches below any given node.
I added a few new methods, and made a minor enhancement to the way the static funcition ScanItems() in TTreeView class works to support a toggle mode.
Here's what I added to TtvItem.prg:
- Code: Select all Expand view
#define TVE_TOGGLE 3
#define TVM_ENSUREVISIBLE TV_FIRST + 20
....
METHOD Toggle() INLINE ;
SendMessage( ::oTree:hWnd, TVM_EXPAND, TVE_TOGGLE, ::hItem )
METHOD MakeVisible() INLINE ;
SendMessage( ::oTree:hWnd, TVM_ENSUREVISIBLE, 0, ::hItem )
And here's what I added to TTreeVie.prg (ehnancements in bold):
[ Note: it seems bold doesn't work inside the code bbcode, so look out for
[ b ] .... [ / b ] and strip it out from the actual code
- Code: Select all Expand view
METHOD CollapseAll( [b]oItem[/b] ) INLINE ScanItems( ::aItems, .f. ), ;
[b]oItem := ::GetSelected(), if( oItem <> nil, oItem:MakeVisible(), nil )[/b]
METHOD CollapseBranch( oItem ) INLINE ;
if( oItem == nil, oItem := ::GetSelected(), nil ), ;
if( oItem <> nil, ( oItem:Collapse(), ScanItems( oItem:aItems, .f. ), oItem:MakeVisible() ), nil )
METHOD ExpandAll( [b]oItem[/b] ) INLINE ScanItems( ::aItems, .t. ), ;
[b]oItem := ::GetSelected(), if( oItem <> nil, oItem:MakeVisible(), nil )[/b]
METHOD ExpandBranch( oItem ) INLINE ;
if( oItem == nil, oItem := ::GetSelected(), nil ), ;
if( oItem <> nil, ( oItem:Expand(), ScanItems( oItem:aItems, .t. ), oItem:MakeVisible() ), nil )
METHOD Toggle() INLINE AEval( ::aItems, { | oItem | oItem:Toggle() } )
METHOD ToggleAll( oItem ) INLINE ScanItems( ::aItems, , .t. ), ;
oItem := ::GetSelected(), if( oItem <> nil, oItem:MakeVisible(), nil )
METHOD ToggleBranch( oItem ) INLINE ;
if( oItem == nil, oItem := ::GetSelected(), nil ), ;
if( oItem <> nil, ( oItem:Toggle(), ScanItems( oItem:aItems, , .t. ), oItem:MakeVisible() ), nil )
....
static function ScanItems( aItems, lExpand[b], lToggle[/b] )
local oItem, i
DEFAULT lExpand := .t.[b], lToggle := .f.[/b]
for i := 1 to Len( aItems )
oItem = aItems[ i ]
[b]if lToggle
oItem:Toggle()
else[/b]if lExpand
oItem:Expand()
else
oItem:Collapse()
endif
if Len( oItem:aItems ) != 0
ScanItems( oItem:aItems[b], lExpand, lToggle[/b] )
endif
next
return nil
As you can see, I added a 3rd param to ScanItems to handle the toggle mode (which overrides lExpand param).
The previously existing methods ExpandAll() and CollapseAll() were just augmented with a call to the new TTvItem method MakeVisible() to ensure that when you have lots of branches in your tree, the selected item remains within the visible area.
The ToggleBranch() method was precisely what I was aiming for; with this new method you just pass the oItem you want to expand all the way down, with a single call. Toggle() will just act like Expand() or Collapse(), only acting upon the specified oItem, but not on the rest of the items below the specified one.
Hope this is useful for others, and Antonio, please add it to FWH.
Regards,
Luis