Updating Hierarchical List Boxes (OpenInsight Specific)
At 27 FEB 1998 06:13:31AM Richard Matsen wrote:
Can anyone advise the best of 'propper' way to update a hierarchical list box?
Should I:
Get_Property List_Ex, modify it and put it back?
Send_Message Delete_Ex then Insert_Ex the modified line?Both seem problematic, but #2 has the least problems.
At 27 FEB 1998 09:06AM Dave wrote:
Richard,
I would use the #2 if you look at our knowledge base there is a posting about Hierarchical list boxes. [url=Http://www.revelation.com/WebSite/knowledge.nsf/88e0581886ff6a0d8525651c004caecf/ee9a96410d0811ea852565a1006ed53e?OpenDocument] This is the link[/url]-DaveRevelation
At 02 MAR 1998 05:53AM Richard Matsen wrote:
Thanks Dave,
Now here's the sneaky bit - I asked that question to ask this one:
When I do a #2, the Insert op puts the new line in "hidden" or collapsed - but I really really want it to be visible, because the user has selected the line in order to edit it - well it must have been visible, eh?
So, am I right in thinking I should send an Expand message to ParentPos. (ParentPos obtained from property Selpos_Ex).
At 02 MAR 1998 09:37AM Cameron Revelation wrote:
Richard,
I believe you can also use Send_Message UPDATE.
Cameron Purdy
Revelation Software
At 02 MAR 1998 10:47AM Dave wrote:
Richard,
There is also a property 'list_ex' which Returns or sets what the list would be if fully expanded. I think this may help.
DaveRevelation
At 03 MAR 1998 04:24AM Richard Matsen wrote:
Hi Dave,
That was my #1 way of updating (see original message), but I found that Selpos_Ex was corrupted after the Set_Property to List_Ex.
I also tried saving a copy of Selpos_Ex, then putting it back after updating List_Ex, but that didn't work either.
Cameron's suggestion of sending the Update message somes promising, I'll give it a wirl & post the results back here.
Regards,
Richard.
At 03 MAR 1998 11:46AM Oystein Reigem wrote:
Richard,
I struggled a lot with hierarchical list boxes last year. I almost became an expert but now I've forgotten all of it.
Or maybe not. I remember I had problems using Send_Message to send messages from the list box event handlers to the list box itself. I couldn't get anything to happen. I don't know why. I had no problems with Send_Message from a different control, e.g a button.
So I would chose (1) over (2), but please tell me if you are successful with Send_Message!
I'm also sceptical about Cameron's suggestion of using UPDATE, because my OI 3.3 online help says this message "Updates the image of an item in a list box with bitmaps", and that's what I've been using it for. Is UPDATE different in newer versions of OI?
You say that you "found that Selpos_Ex was corrupted after the Set_Property to List_Ex. You also tried saving a copy of Selpos_Ex, then putting it back after updating List_Ex, but that didn't work either". I had a quite similar experience with Selpos and List (setting the latter destroys the former), but the strategy you tried with Selpos_Ex/List_Ex *does* work with Selpos/List. Are you sure you did it right, i.e, are you sure the new value of Selpos_Ex should be identical to the old one? (Maybe you think this is a silly question, but I'm not quite sure of what you do.)
Maybe I should ask that - what is it really that you want to do? You have a hierarchy of values (text strings) that you display in a hierarchical list box, right? The user may expand and collapse by double-clicking, right? The user may also select (single-click on) a line, press some keyboard key (key combination) or window button, get up a dialog box or something, and change the value. Am I right? (Then maybe (2) will work after all since the handler that does the Send_Message is in a different control.) Furthermore, changing a value is the only change allowed. the user cannot delete or insert values. Right?
- Oystein -
At 04 MAR 1998 08:29AM Richard Matsen wrote:
Hi Oystein,
The basic setup (in a simplified test) is as follows:
The window has a hierarchical listbox which represents records from various tables.
The window also has some edit controls where the user can modify details of the selected record, but of course I want to refresh the listbox with the changes.
Modifying LIST_EX directly causes SELPOS_EX to return null after setting LIST_EX.
Saving SELPOS_EX and setting it back to the saved property doesn't work - it still returns null afterwards.
Sending UPDATE message doesn't work - as you say, it only seems to apply to the image bit & ignores the changed text. (I'm on OI 3.5).
Sending DELETE_EX then INSERT_EX works, but inserts the changed item as hidden or collapsed.
Sending EXPAND to the parent works, except if the changed item is at level 1 - then the only option is to send EXPAND to level 0, but then any other level 1 items which were collapsed are expanded also.
This is as close as I get to perfect, but is not really good enough since I want the list to look the same before and after the edit, except for the changed line.
The simplified code I'm using for testing is as follows. Attach it to a window with one listbox and two edit lines.
Attach window and control events as indicated by the code.
Modify the entry in editline1 and lose focus by clicking on editline2. (Hope this is clear enough).
Compile Function RM_Test( CtrlEntID, mode, Param1, Param2, Param3, Param4, Param5 )
Declare Function Get_Property
Declare Function Set_Property
Declare Function Send_Message
EQU Max_Levels% to 7
ans='
win=CtrlEntID1,'.'
convert @lower_case to @upper_case in mode
Begin Case
Case mode=CREATE'
gosub CreateCase mode=CHANGED'
gosub ChangedCase mode=LOSTFOCUS'
gosub LostfocusCase mode=DBLCLK'
gosub DblclkEnd Case
Return ans
*
*—–+
Create:
*—–+
list=1-1:a"
list=1-1:b"
list=1-2:1"
list=1-2:2"
list=1-2:3"
list=1-1:c"
list=1-2:4"
list=1-3:x"
list=1-3:y"
list=1-3:z"
list=1-2:5"
list=1-1:d"
i=1
AtWindow=CtrlEntID1,'.'
CtrlArray = AtWindow : ".LISTBOX"
PropArray = "LIST"
DataArray = List
CtrlArray := @Rm : AtWindow : ".LISTBOX"
PropArray := @Rm : "SELPOS"
DataArray := @Rm : I
CtrlArray := @Rm : AtWindow : ".LISTBOX"
PropArray := @Rm : "TOPPOS"
DataArray := @Rm : I
DataArray = Set_Property(CtrlArray, PropArray, DataArray)
Return
*
*——+
Changed:
*——+
SelposEx=Get_Property( CtrlEntID, "SELPOS_EX" )
ListEx =Get_Property( CtrlEntID, "LIST_EX" )
old=Set_Property( CtrlEntID1,'.':'.EDITLINE_1', 'TEXT', Field(ListEx,":",2) )
Return
*
*——–+
Lostfocus:
*——–+
spdata=Get_Property( CtrlEntID1,'.':'.LISTBOX', "SELPOS_EX" )
SelPosEx =spdata ;* Current pos in fully expand list.
Indent =spdata ;* Indent level of selection.
NumChildren=spdata ;* No leaf nodes below: +ve if expanded, -ve if hidden, 0 if none.
SelPos =spdata ;* Current pos in displayed list.
ParentPos =spdata ;* Selpos of parent node.
ListEx =Get_Property( CtrlEntID1,'.':'.LISTBOX', "LIST_EX" )
List =Get_Property( CtrlEntID1,'.':'.LISTBOX', "LIST" )
debug
If List=ListEx Then
debugEnd
data=Get_Property( CtrlEntID, "TEXT" )
level=ListEx1,'F:'
entry=level :':': data
These are the ways I've tried to update the listbox. * Method 1: Change LIST_EX, using Get_Property & Set_Property *
/*
spdata1=Get_Property( win:'.LISTBOX', 'SELPOS_EX' ) ;* Before update - spdata OK.ListEx=entryold=Set_Property( win:'.LISTBOX', 'LIST_EX', ListEx )spdata2=Get_Property( win:'.LISTBOX', 'SELPOS_EX' ) ;* After update - spdata NULL.old=Set_Property( win:'.LISTBOX', 'SELPOS_EX', spdata1 ) ;* Try restoring the saved value.spdata3=Get_Property( win:'.LISTBOX', 'SELPOS_EX' ) ;* Test it again - still blank,
conclude that setting List_Ex is a no-no.
This method fails because SelposEX is return null on second edit.*/
* Method 2: Change LIST property * /* list=Get_Property( CtrlEntID1,'.':'.LISTBOX', 'LIST' ) SelPos=Get_Property( CtrlEntID1,'.':'.LISTBOX', 'SELPOS' ) List=entry old=Set_Property( CtrlEntID1,'.':'.LISTBOX', 'LIST', list ) */ * No good - doesn't update the ListEx property. * Method 3: Use DELETE_EX and INSERT_EX to remove the old line then put in the modified
chunk=Send_Message( win:'.LISTBOX', "DELETE_EX", SelPosEx )chunk=entryrv=Send_Message( win:'.LISTBOX', "INSERT_EX", SelPosEx, chunk )
This method "works", but the display looks as if the insert has not occured,
i.e the changed sibling is not visible but the unchanged sibling is.
If you dblclk the parent, the display appears as expected, SO..If indent=1 Thenrv=Send_Message( win:'.LISTBOX', "EXPAND", 0, Max_Levels% )End Elserv=Send_Message( win:'.LISTBOX', "EXPAND", ParentPos, Max_Levels% )Endold=Set_Property( win:'.LISTBOX', "SELPOS", Selpos )* Method 4: Send UPDATE message with changed data /* rv=Send_Message( win:'.LISTBOX', "UPDATE", SelposEx, entry ) */ * No good - only used to update the image number, takes no notice of the changed text. *
Return
*
*—–+
DblClk:
*—–+
ListEx=Get_Property( CtrlEntID, "LIST_EX" )
data=Get_Property( CtrlEntID, "SELPOS_EX" )
SelPosEx =data ;* Current pos in fully expand list.
Indent =data ;* Indent level of selection.
NumChildren=data ;* No leaf nodes below: +ve if expanded, -ve if hidden, 0 if none.
SelPos =data ;* Current pos in displayed list.
Parent =data ;* Selpos of parent node.
If NumChildren ] 0 Then
rv=Send_Message( CtrlEntID, "EXPAND", SelPos, 7 )End
Return 1
*
At 06 MAR 1998 10:17AM Oystein Reigem wrote:
Richard,
I think I managed to fix it, but perhaps with more manipulation of the list box than you'd like.
- Oystein -
* Method 3: Use DELETE_EX and INSERT_EX to remove the old line then put in the modified **
/* ¤¤¤ */equate true$ to 1equate false$ to 0.../* ¤¤¤ we will delete and reinsert a chunk,but before we delete we examine and saveinfo on which nodes are expanded(we save their non-expanded position).but for some reason we have to go one level upand do this from and including the parent.if we are already on level 1 we have to do the whole hierarchy */Done=false$if Indent=1 thenExpandArr='ExpandArr=0StartPos=1end elseExpandArr='StartPos=ParentPosendPos=StartPosloopPosEx=Send_Message( @Window :'.LISTBOX', "SELPOS_EX_BY_POS", Pos )CurrIndent=PosExif (Pos ] StartPos) and (CurrIndent ] 0 then /* No leaf nodes below: +ve if expanded, -ve if hidden, 0 if none. */ExpandArr=PosEx /* Position in list (SELPOS value) */endPos += 1repeatchunk=Send_Message( @Window :'.LISTBOX', "DELETE_EX", SelPosEx )chunk=entryrv=Send_Message( @Window:'.LISTBOX', "INSERT_EX", SelPosEx, chunk )
This method "works", but the display looks as if the insert has not occured,
i.e the changed sibling is not visible but the unchanged sibling is.
If you dblclk the parent, the display appears as expected, SO../* ¤¤¤ is this true? I had to dblclk twice,and it didn't recreate the expanded structure properly either*//* ¤¤¤ re-expand the nodes, but only the ones that were expanded before.note! this would not have worked if a collapsed hierarchy could contain expanded sub-hierarchies.but in OI hierarchical list boxes every node in a collapsed hierarchy is collapsed */ExpCount=count(ExpandArr, @FM) + (ExpandArr '')for X=1 to ExpCountrv=Send_Message( @Window :'.LISTBOX', "EXPAND", ExpandArr, 1 )next X/* ¤¤¤ I hadn't time to check this one. I think it worked without */old=Set_Property( @Window :'.LISTBOX', "SELPOS", Selpos )*/