Page 1 of 1

Synchronizing variables in Listboxes

PostPosted: Fri Apr 03, 2015 12:53 pm
by dpayer
I would like to be able to populate a listbox with a variable and then when items are added or removed, the original variable would be synchronized with the contents of the box. I could write a function to do this but I would have to have a hook that would indicate when a change had been made in the listbox, not merely a selection change.

As is, if you populate with a variable and then add or delete entries using ListboxAddItem, or ListboxDeleteItem, the original variable remains the same but the display no longer reflects the original variable that set it.

I've created a demonstration of the issue. Create a new 640x480 app and paste the following code in it:
Code: Select all
{NeoBook 5 Objects}
NeoBookVer=5.80
ObjectType=10
Name=ListBox1
X=204
Y=39
W=203
H=366
Anchor=0
Text=[OriginalList]
VarName=[ListBox1]
VarType=0
XPTheme=Yes
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=1
FontCharset=1
TextColor=0
TabOrder=2
ObjectType=3
Name=PushButton1
X=38
Y=41
W=124
H=30
Anchor=0
Text=Set List
Hint= Assign new values to variable OriginalList
Align=2
ImageStyle=0
XPTheme=Yes
ObjAction=SetVar "[originalList]" "apple[#13]orange[#13]banana[#13]"¶RefreshObject "ListBox1"¶ListBoxSize "ListBox1" "[listboxlen]"¶StrParse "[OriginalList]" "[#13]" "[OriginalList]" "[OLlen]"
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
TabOrder=3
ObjectType=3
Name=PushButton2
X=207
Y=409
W=204
H=30
Anchor=0
Text=Show value of OriginalList var
Hint=apple, orange, banana
Align=2
ImageStyle=0
XPTheme=Yes
ObjAction=Alertbox "test" "The value of the original list var is:|[OriginalList]"
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
TabOrder=4
ObjectType=3
Name=PushButton3
X=38
Y=197
W=124
H=30
Anchor=0
Text=Clear Listbox
Align=2
ImageStyle=0
XPTheme=Yes
ObjAction=ListBoxSize "ListBox1" "[listboxlen]"¶StrParse "[OriginalList]" "[#13]" "[test]" "[OLlen]"¶Alertbox "test" "ListboxSize is [listboxlen]"¶¶Loop "1" "[listboxlen]" "[CTR]"¶SetVar "[DisplayNum]" "[listboxlen]+1-[ctr]"¶StickyNote "-1" "-1" "Deleting listbox item #[DisplayNum]" "500"¶ListBoxDeleteItem "ListBox1" "[DisplayNum]"¶Endloop¶ListBoxSize "ListBox1" "[listboxlen]"¶StrParse "[OriginalList]" "[#13]" "[OriginalList]" "[OLlen]"
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
TabOrder=5
ObjectType=3
Name=PushButton4
X=38
Y=93
W=124
H=30
Anchor=0
Text=Add item to OL Var
Hint=Add item to OriginalList variable string
Align=2
ImageStyle=0
XPTheme=Yes
ObjAction=InputBox "Add to list" "This will add to the variable OriginalList |and refresh the listbox" "[NewItem]"¶¶SetVar "[originalList]" "[OriginalList][NewItem][#13]"¶RefreshObject "ListBox1"¶SetVar "[newitem]" ""¶ListBoxSize "ListBox1" "[listboxlen]"¶StrParse "[OriginalList]" "[#13]" "[OriginalList]" "[OLlen]"
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
TabOrder=6
ObjectType=3
Name=PushButton5
X=38
Y=144
W=124
H=30
Anchor=0
Text=Add item to listbox
Hint=Add item using NB ListBoxAddItem
Align=2
ImageStyle=0
XPTheme=Yes
ObjAction=InputBox "Add to listbox" "This will add an item to the listbox itself|and then refresh the object" "[NewItem]"¶ListBoxAddItem "ListBox1" "0" "[NewItem]"¶RefreshObject "ListBox1"¶SetVar "[newitem]" ""¶ListBoxSize "ListBox1" "[listboxlen]"¶StrParse "[OriginalList]" "[#13]" "[OriginalList]" "[OLlen]"
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
TabOrder=7
ObjectType=8
Name=Text1
X=426
Y=47
W=174
H=40
Anchor=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
Text={\rtf1\ansi\deff0\deftab254{\fonttbl{\f0\fnil\fcharset1 Arial;}}{\pard{\ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs22\cf0 Listbox size is: [listboxlen]}}}
HMargin=0
VMargin=0
LineColor=0
LineWidth=0
LineStyle=0
FillColor=16777215
FillPattern=0
TabOrder=8
ObjectType=8
Name=Text2
X=411
Y=383
W=226
H=40
Anchor=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
Text={\rtf1\ansi\deff0\deftab254{\fonttbl{\f0\fnil\fcharset1 Arial;}}{\pard{\ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs22\cf0 #Lines in OriginalList variable: [OLlen]}}}
HMargin=0
VMargin=0
LineColor=0
LineWidth=0
LineStyle=0
FillColor=16777215
FillPattern=0
TabOrder=9
ObjectType=8
Name=Text3
X=202
Y=2
W=244
H=42
Anchor=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
Text={\rtf1\ansi\deff0\deftab254{\fonttbl{\f0\fnil\fcharset1 Arial;}}{\pard{\ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs22\cf0 Listbox populated with "OriginalList" \par\ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs22\cf0 variable using #13 separators}}}
HMargin=0
VMargin=0
LineColor=0
LineWidth=0
LineStyle=0
FillColor=16777215
FillPattern=1
TabOrder=10
ObjectType=9
Name=TextEntry1
X=431
Y=94
W=183
H=261
Anchor=0
Text=The list box is populated at startup by setting the variable [OriginalList].¶¶Click Set List and this resets the value of the variable [OriginalList]¶¶Click Add item to OL (OrigianList) Var and you will be prompted to add a value to the listbox. Note how the Listbox size and the #lines in the OL variable are still the same.¶¶Click Add item to listbox. This prompts you for a value and then inserts it using the ListboxAddItem command.Note how the listbox has 5 items but the OL variable is still only 4 lines. Click the Show Value of Originallist var button at bottom. You see it does not show the newly added item.¶¶Click the Add item to OL Var button and add another item. Notice how it overwrites the last item added by ListboxAddItem.¶¶Again add an item to listbox and see how it is added to the listbox but is not in the OriginalList variable. Also Listbox size and OriginalList variable have different numbers of lines.¶¶Click Clear Listbox button. This usese the ListBoxDeleteItem command. Note that the listbox is empty but the OriginalList variable is as was.
VarName=[TextEntry1]
Align=1
EditMultiLine=Yes
EditLen=0
LineColor=0
LineWidth=1
LineStyle=0
FillColor=16777215
FillPattern=0
Font=Arial
FontSize=11
FontStyle=0
FontCharset=1
TextColor=0
TabOrder=11


Follow the steps I have typed in to see the issues.
Image

As mentioned, if I had a way to know when a change occurred in the list, not just a selection change, I could address this. As it is, maybe NB could have a new function in this area. Synchronizing the listbox contents with the variable that originally set the value of the listbox. Make this an option when defining the object.

Image

Is there a way currently to know when a change has been made to the listbox?

Re: Synchronizing variables in Listboxes

PostPosted: Fri Apr 03, 2015 4:00 pm
by Neosoft Support
This is an interesting question. Since the only way to add or remove something from a listbox is via code, you already know when it's being modified because you're the one doing it. You could manually add and remove items directly from the [OriginalList] variable, but that requires more code and isn't as convenient as using ListBoxAddItem and ListBoxDeleteItem. What you could do if you wanted to use the ListBox actions, is call a subroutine whenever you make changes that affect the list. For example:

:UpdateList
ListBoxGetItem "ListBox1" "ALL" "[NewList]"
StrReplace "[NewList]" "|" "[#13]" "[OriginalList]" ""
Return

A new feature that allowed you to specify a subroutine to execute whenever a variable's value changes is something that might be worth considering for the future. However, for variables that are updated a lot such a feature could become a big performance drag.

Re: Synchronizing variables in Listboxes

PostPosted: Fri Apr 03, 2015 4:24 pm
by Gaev
David Payer:

I would like to be able to populate a listbox with a variable and then when items are added or removed, the original variable would be synchronized with the contents of the box.


This Subroutine will re-create the contents of the ListBox in a format like the "Original Variable" ...
Code: Select all
:VarFromListBox
SetVar "[ListItems]" ""
ListBoxSize "ListBox1" "[ListBoxItemCount]"

Loop "1" "[ListBoxItemCount]" "[thisItemNumber]"
   ListBoxGetItem "ListBox1" "[thisItemNumber]" "[thisItemText]"
   SetVar "[ListItems]" "[ListItems][thisItemText][#13]"
EndLoop

... may need to remove final [#13] here

Return


I could write a function to do this but I would have to have a hook that would indicate when a change had been made in the listbox, not merely a selection change.

So whenever you have a ListboxAddItem, ListBoxChangeItem or ListBoxDeleteItem, just follow it with a GoSub "VarFromList".

Perhaps I am missing something.

Re: Synchronizing variables in Listboxes

PostPosted: Mon Apr 06, 2015 6:33 am
by dpayer
Thanks Gaev,

Your suggestion works for adjustments made to the listbox using the listboxadditem and listboxdeleteitem commands.

It may be that I cannot mix the two methods of adding times to the list box (command and variable update) and keep the variable consistent with the actual display.

I'll experiment a bit more.

Re: Synchronizing variables in Listboxes

PostPosted: Tue Aug 18, 2015 9:22 pm
by radz123
Hi guys, I happen to have an issue quite similar to this.

What I need is to a subroutine to select all values on Listbox1 and Listbox 2

How can I do that?

Re: Synchronizing variables in Listboxes

PostPosted: Wed Aug 19, 2015 6:06 am
by Gaev
radz123:

What I need is to a subroutine to select all values on Listbox1 and Listbox 2
How can I do that?


Here is a generic subroutine that will append all items from the Listbox (specified in [thisListBox]) to the variable [Listitems] ...
Code: Select all
:AppendListItems
ListBoxSize "[thisListBox]" "[ListBoxItemCount]"

Loop "1" "[ListBoxItemCount]" "[thisItemNumber]"
   ListBoxGetItem "[thisListBox]" "[thisItemNumber]" "[thisItemText]"
   SetVar "[ListItems]" "[ListItems][thisItemText][#13]"
EndLoop

Return

... the items are separated by the newline character [#13].

So now, you can call it twice like this ...
Code: Select all
SetVar "[ListItems]" ""

SetVar "[thisListBox]" "ListBox1"
GoSub "AppendListItems"

SetVar "[thisListBox]" "ListBox2"
GoSub "AppendListItems"

... remove final [#13]
StrLen "[ListItems]" "[ListItemsSize]"
SubStr "[ListItems]" "1" "[ListItemsSize]-1" "[ListItems]"

... try it out and post descriptions of any problems you might encounter (as I have not run it myself).

Re: Synchronizing variables in Listboxes

PostPosted: Wed Aug 19, 2015 7:12 am
by mishem
Loop "1" "[ListBoxItemCount]" "[thisItemNumber]"
ListBoxGetItem "ListBox1" "[thisItemNumber]" "[thisItemText]"
SetVar "[ListItems]" "[ListItems][thisItemText][#13]"
EndLoop


It may take a long time if the list is large.
Use:

Code: Select all
GetObjectInfo "ListBox1" "Caption" "[ListItems]"


The elements are separated by a vertical bar |

Just as quickly you can fill the list.

Code: Select all
SetObjectCaption "ListBox1" "[NewListItems]"