Popup Menu/Timer

First issue: Unable to populate a Popup Menu with desired values upon window opening. The Popup Menu always comes up blank until clicked on. As a workaround in the main window, I added a timer that fired milliseconds after the window opened and populated the Popup Menu (PopupMenu1.SelectedRowIndex = 3). This worked in the main window but I have yet to get a timer to fire in an instance of another window I need the Popup Menu in. This I do not understand. As for getting the popup menu to behave as I wish does anyone else have a suggestion. I would like to set the Popup Menu to the desired value when open and be visible.

In the Activate event:

[code]Static bActivated as boolean
if not bActivated then

popupmenu1.listindex = 3
//or PopupMenu1.SelectedRowIndex = 3 if that works for you

bActivated = true
end if[/code]

have no problem, xojo 2019r3.1 and windows desktp project.
it would be blank if your index is out of bounds. index start from 0 to count-1

Window Open Event it open and show entry D

[code]Sub Open() Handles Open
PopupMenu1.RemoveAllRows

PopupMenu1.AddRow “A”
PopupMenu1.AddRow “B”
PopupMenu1.AddRow “C”
PopupMenu1.AddRow “D”

PopupMenu1.SelectedRowIndex = 3

End Sub
[/code]

This is what I had used to populate:

var i as Integer // Set Away max/min me.DeleteAllRows for i = 40 to 60 me.AddRow str(i) next

and where is the SelectedRowIndex ?
which event is that because you used “Me”?

[quote=493390:@Markus Rauch]and where is the SelectedRowIndex ?
which event is that because you used “Me”?[/quote]
In this test example, I first placed it in the open event of the PopupMenu1 which does not work and then in a timer action event (PopupMenu1.SelectedRowIndex = 3) which does after the timer fires. Unfortunately, this workaround will not work in the window I would like to use it in since a timer will not fire for some reason in that window. I’m not sure why yet.

ah now i understand, i tested this fill and select in the window open event not in the PopupMenu open.

using this in the popup open event works too, at least at 2019r3.1
you have a older version of xojo?

[code]Sub Open() Handles Open
Me.RemoveAllRows

Me.AddRow “A” '0
Me.AddRow “B” '1
Me.AddRow “C” '2
Me.AddRow “D” '3

Me.SelectedRowIndex = 3
End Sub
[/code]

[quote=493387:@Jeff Tullin]In the Activate event:

[code]Static bActivated as boolean
if not bActivated then

popupmenu1.listindex = 3
//or PopupMenu1.SelectedRowIndex = 3 if that works for you

bActivated = true
end if[/code][/quote]

Jeff, could you please give me a better idea of what you are doing with this code?

Static bActivated as boolean
if not bActivated then
XXXXXX
bActivated = true

[quote=493389:@Clifford Coulter]var i as Integer
// Set Away max/min
me.DeleteAllRows
for i = 40 to 60
me.AddRow str(i)
next[/quote]

This is fine, but as Jeff and Markus pointed out, you also have to set the ListIndex or SelectedRowIndex. This property defaults to -1, so if you don’t explicitly set it to a value between 0 and ListCount-1, the popup will not show anything.

[quote=493419:@Markus Rauch]ah now i understand, i tested this fill and select in the window open event not in the PopupMenu open.

using this in the popup open event works too, at least at 2019r3.1
you have a older version of xojo?

[code]Sub Open() Handles Open
Me.RemoveAllRows

Me.AddRow “A” '0
Me.AddRow “B” '1
Me.AddRow “C” '2
Me.AddRow “D” '3

Me.SelectedRowIndex = 3
End Sub
[/code][/quote]
Yes, you are right Markus. The problem seems to be associated with the fact that I am repopulating the values in the popup depending on in my case which area device I am trying to set. Room temperatures would be different than domestic hot water tank temperatures in this case. Other words the popup it being repopulated with different values on the run as I choose the device it is associated with. This is causing the blank popup.

Now that I’ve found the first issue I notice another rears its head. The values from this popup menu are placed in an array when a new selection in the popup menu is made. I notice when the window with the control first opens the chosen (Me.SelectedRowIndex = 3) value is entered into the array which is good. The problem is when I choose the next value it is not entered. After that all subsequent values are.

In the popup change event this code sends the info to the array:
Clone_of_Heating_Prefs_Original_Array(2, Economy_or_Normal, 6, Zone_Selected, 5) = me.ListIndex + val(me.list(0))

You are right on the mark with this one. Now if you can shed some light concerning the question I just entered to Markus.

If all is equal, should I be able to change the populated popup with new values on the run.

After further working with this control I find if the popup is accessed each time before repopulating it will continue to work. if not it freezes up.

[code]Var i,awayMin,awayMax as integer
select case Zone_Selected
case 0
awayMin = 55
awayMax = 68
case 1
awayMin = 55
awayMax = 68
case 2
awayMin = 55
awayMax = 68
case 3
awayMin = 55
awayMax = 90
case 4
awayMin = 55
awayMax = 100
end select

// Set Away max/min
awayTemp.DeleteAllRows

for i = awayMin to awayMax
awayTemp.AddRow str(i)
next
awayTemp.SelectedRowIndex = 0
[/code]

because the PopupMenu is a user interface you should change it by button action or menu event.
maybe it freezes up because you change it too much?
if you use this one popup with different zones you need to store the actual value somehow.

button 1

[code]Var currentTemp As Integer = 60

Var awayMin, awayMax As Integer

ZoneTemp 2, awayMin, awayMax

UpdatePopUp PopupMenu1, awayMin, awayMax, currentTemp[/code]
button 2

[code]Var currentTemp As Integer = 80

Var awayMin, awayMax As Integer

ZoneTemp 3, awayMin, awayMax

UpdatePopUp PopupMenu1, awayMin, awayMax, currentTemp
[/code]
button 3

[code]Var currentTemp As Integer = 99

Var awayMin, awayMax As Integer

ZoneTemp 4, awayMin, awayMax

UpdatePopUp PopupMenu1, awayMin, awayMax, currentTemp[/code]

some helpers

[code]Public Sub UpdatePopUp(awayTemp As PopupMenu, awayMin As Integer, awayMax As Integer, selectValue As Integer)
awayTemp.RemoveAllRows
awayTemp.SelectedRowIndex = 0

For i As Integer = awayMin To awayMax
awayTemp.AddRow Str(i)
If selectValue = i Then awayTemp.SelectedRowIndex = awayTemp.LastAddedRowIndex
Next

End Sub
[/code]

[code]Public Sub ZoneTemp(zone As Integer, Byref awayMin As Integer, Byref awayMax As Integer)
Select Case zone
Case 0
awayMin = 55
awayMax = 68
Case 1
awayMin = 55
awayMax = 68
Case 2
awayMin = 55
awayMax = 68
Case 3
awayMin = 55
awayMax = 90
Case 4
awayMin = 55
awayMax = 100
Case 5
Raise New RuntimeException("invalid zone number " + zone.ToString ,666)
End Select

End Sub
[/code]

Markus, this seems powerful to me in a way that I am not familiar with so I have questions for you in the rem statements below and my interpretations. It took me some time to get my head wrapped around your great example. I am very grateful for you taking the time to do this for me and believe it will help me immensely with the way I think about controls.

button 1

[code]Var currentTemp As Integer = 60
Var awayMin, awayMax As Integer

ZoneTemp(2, awayMin, awayMax) rem Cass 2 and min/max

Rem Markus are you sending the control PopupMenu1 to UpdatePopUp?
UpdatePopUp(PopupMenu1, awayMin, awayMax, currentTemp) // do not need () UpdatePopUp PopupMenu1, awayMin, awayMax, currentTemp
[/code]
button 2

[code]Var currentTemp As Integer = 80

Var awayMin, awayMax As Integer

ZoneTemp 3, awayMin, awayMax

UpdatePopUp PopupMenu1, awayMin, awayMax, currentTemp[/code]

button 3

[code]Var currentTemp As Integer = 99

Var awayMin, awayMax As Integer

ZoneTemp 4, awayMin, awayMax

UpdatePopUp PopupMenu1, awayMin, awayMax, currentTemp
[/code]

some helpers

[code]Public Sub UpdatePopUp(awayTemp As PopupMenu, awayMin As Integer, awayMax As Integer, selectValue As Integer)
AwayTempPopupMenu.RemoveAllRows // Remove all rows first.

Rem Markus I am not seeing this next code line as doing anything for us placed here.
Rem Used to get or set the selected item number. The first item is numbered zero.
AwayTempPopupMenu.SelectedRowIndex = 0

For i As Integer = awayMin To awayMax
AwayTempPopupMenu.AddRow Str(i)

Rem if the value of the current row (SelectedRowIndex) in the popup is i then the index number of the popup is the (LastAddedRowIndex) last row added index number added to the popup
If selectValue = i Then AwayTempPopupMenu.SelectedRowIndex = AwayTempPopupMenu.LastAddedRowIndex
Next
[/code]

[code]Rem Mark can you explain how Byref allows UpdatePopUp to see awayMax/awayMin. If set as Byref does that make them look like a property? We are not passing awayMax/awayMin to this Zonetemp

Public Sub ZoneTemp(zone As Integer, Byref awayMin As Integer, Byref awayMax As Integer)
Select Case zone
Case 0
awayMin = 55
awayMax = 68
Case 1
awayMin = 55
awayMax = 68
Case 2
awayMin = 55
awayMax = 68
Case 3
awayMin = 55
awayMax = 90
Case 4
awayMin = 55
awayMax = 100
Case 5
Raise New RuntimeException("invalid zone number " + zone.ToString ,666)
End Select

End Sub[/code]

yes you can send a control also as parameter to a method.

AwayTempPopupMenu.SelectedRowIndex = 0 i used if selectedValue would not be found in the for next.

selectValue is your selected row wish, means the number you will select
i was the number/value you add to a new row
if your value was found in the loop this row get selected

Byref means you can change the value inside a method and the value is also changed in the method one above where the variables was defined. its similar a return value.

[quote=493483:@Markus Rauch]yes you can send a control also as parameter to a method.

AwayTempPopupMenu.SelectedRowIndex = 0 i used if selectedValue would not be found in the for next.

selectValue is your selected row wish, means the number you will select
i was the number/value you add to a new row
if your value was found in the loop this row get selected

Byref means you can change the value inside a method and the value is also changed in the method one above where the variables was defined. its similar a return value.[/quote]

Some times it takes a good project to learn something like XOJO. This new concept of passing controls to methods seems like a game-changer. A dozen or so years ago I was happy just to get my home automation system up and running although the code was probably a mess. You would never know it from the outside though. It looked and run elegantly 24/7. This time I would like to take the time to do better. So if you see some concept that you feel is important that I might be missing please help me out with it. I will always have more questions. Thanks, Markus I learned a lot today.

I have been giving thought to a descent approach to capturing new values selected in the popup menu we have been working with. I store the values in the clone array and use the values from the clone array to set the popup menu for each zone selected. I used your code in UpdatePopUp method but added code to set the popup menu from the clone array and set a default if none are matching.

AwayTempPopupMenu.RemoveAllRows // Remove all rows first.

For i As Integer = awayMin To awayMax
AwayTempPopupMenu.AddRow Str(i)

If i =Clone_of_Heating_Prefs_Original_Array(2, Economy_or_Normal, 6, Zone_Selected, 5) Then
AwayTempPopupMenu.SelectedRowIndex = AwayTempPopupMenu.LastAddedRowIndex
else
AwayTempPopupMenu.SelectedRowIndex = 5 'if not set, set to 60 as default
end
Next

I first thought I would use the change event in the popup but it fires every time I change zones with the zone buttons. I could ignore this first change event but maybe you have a better approach to capturing the new user-selected values.

[quote=493543:@Clifford Coulter]For i As Integer = awayMin To awayMax
AwayTempPopupMenu.AddRow Str(i)

If i =Clone_of_Heating_Prefs_Original_Array(2, Economy_or_Normal, 6, Zone_Selected, 5) Then
AwayTempPopupMenu.SelectedRowIndex = AwayTempPopupMenu.LastAddedRowIndex
else
AwayTempPopupMenu.SelectedRowIndex = 5 'if not set, set to 60 as default
end
Next[/quote]

you can see better what is wrong, u will find the 8 only once else you select a default row

For i = 1 To 10 AddRow i If i = 8 Then SelectedRow i else SelectedRow 5 end if Next

you could use a flag var found = false before the loop.
set found = true if you selected your value and after the for next you check the flag
if found = false then set the default value but i would do a search and not using a fix index.

[quote=493543:@Clifford Coulter]For i As Integer = awayMin To awayMax
AwayTempPopupMenu.AddRow Str(i)

If i =Clone_of_Heating_Prefs_Original_Array(2, Economy_or_Normal, 6, Zone_Selected, 5) Then
AwayTempPopupMenu.SelectedRowIndex = AwayTempPopupMenu.LastAddedRowIndex
else
AwayTempPopupMenu.SelectedRowIndex = 5 'if not set, set to 60 as default
end
Next[/quote]
If I had a nickel for every time I’ve seen this coding error (or done it myself). Markus alluded to it, but let me explain it a little more fully. This code will only work if i is equal to awayMax (or if the selected item happens to be 5). Say awayMin is 4 and awayMax is 7 and the desired index is 6. The code will do the following:

i=4: doesn’t match, set SelectedRowIndex = 5
i=5: doesn’t match, set SelectedRowIndex = 5
i=6: matches, set SelectedRowIndex = 6
i=7: doesn’t match, set SelectedRowIndex to 5

So when it finishes, SelectedRowIndex is wrong. You need to either save the rowindex in a temp variable, or exit the loop when you find the match. I would go with a temp variable.

dim rowindex as integer

rowindex = 5 // initialize to default value
For i As Integer = awayMin To awayMax
   AwayTempPopupMenu.AddRow Str(i)

   If i =Clone_of_Heating_Prefs_Original_Array(2, Economy_or_Normal, 6, Zone_Selected, 5) Then
      rowindex = AwayTempPopupMenu.LastAddedRowIndex
   end
Next
AwayTempPopupMenu.SelectedRowIndex = rowindex

Also, you mention a “clone” of the array. Do you have code that actually copies the values of the array, one by one, into a new array? Or are you just passing a reference to the array and thinking it’s a clone, when actually it is one and the same array? I only ask because that is another common mistake.