Possible bug in Popup Menu control

Feedback Case Number: N/A

I’ve noticed behavior in the Popup Menu control that feels like a bug. As far as I can determine it is not possible to set the “SelectedRowIndex” from within a For loop. I’ve created a simple application that looks like this:

The related code from the window’s opening event is shown below:

// Purpose: This code illustrates a possible bug in the Popup Menu control
// Details:
// - The code attempts to set the state of a Popup Menu to a specific value
// - Two ways of doing this are illustrated using two Popup Menu controls
// - The code mimics the scenario of the specific value being read from a database 


Var flavours() As String 
flavours.Add("Chocolate")
flavours.Add("Melon")
flavours.Add("Strawberry")
flavours.Add("Vanilla")

Var flavour_read_from_database As String = "Melon"  // Imagine this being read from a database
Var current_index As Integer = 0

// This For loop DOES NOT set the Popup Menu control to "Melon"
For Each flavour As String in flavours
  If flavour = flavour_read_from_database Then
    Self.FailingFlavoursPM.SelectedRowIndex = current_index // Does not work!  Is this a bug?
  Else 
    current_index = current_index + 1
  End If
  Self.FailingFlavoursPM.AddRow(flavour)
Next


// This For loop sets the Popup Menu control to "Melon"
current_index = 0
Var selected_row_index As Integer = 0
For Each flavour As String in flavours
  If flavour = flavour_read_from_database Then
    selected_row_index = current_index 
  Else 
    current_index = current_index + 1
  End If
  Self.WorkingFlavoursPM.AddRow(flavour)
Next
Self.WorkingFlavoursPM.SelectedRowIndex = selected_row_index

Am I doing something wrong or is this a bug?

Cheers!!

Dermot

It seems to work here, recreating your example using your code without modification. Do you have other code that runs elsewhere, like the PopupMenu’s SelectionChanged event? Would be best to provide the example project you built so that we can easily reproduce the issue.

Project:
pm_set_forloop.xojo_binary_project.zip (5.4 KB)

Why not use the SecectRowWithTag or SelectRowWithText methods, rather than looping?

For each does not guarantee to loop the elements in index order. You are better using

For nIndex = 0 to popMenu.LastRowIndex
      If popMenu.RowTextAt( nIndex ) = Field then
            PopMenu.SelectedRowIndex = nIndex
      End
Next

Or better still

popMenu.SelectRowWithText( “Melon” )

Thanks for taking a look at this, Anthony!

I’ve kept the project clean, here it is.

Possible_bug_in_PopupMenu.xojo_binary_project.zip (5.8 KB)

By the way, I’m using the very latest release of Xojo (2026V2.1)

I wouldn’t necessarily count on the row tag being populated or unique. You’re likely adding another loop after the fact when you can select the appropriate row while adding the items to the control. For optimization, I’d prefer to do it in the loading loop.

That’s neat. I see it in your example but not mine. I’m assuming my example also works for you.

In the loop that doesn’t work it looks you are trying to set the selected row index before you have added the row.

Yeah, changing the order fixes it, but I don’t think the SelectedRowIndex was supposed to be validated like that (hence it works in my example).

Correct! Your example works for me as well.

It’s a neat little quirk. Either way, one of these is misbehaving. You should open a case.

I modified both examples identically to print to debuglog, and see different messaging:

That explains it, Kevin! Thanks! A bit odd that it worked for Anthony, but moving the line of code to before the If statement fixes my problem. However, shouldn’t I have got an error when setting the index to an impossible value? Maybe there is still a bit of a bug here!

There’s definitely still a bug, but PopupMenu has never raised an OutOfBoundsException (most UI controls don’t validate the way you expect and raise exceptions). Maybe it should? Either way, a case will give Xojo a chance to take a look at it and decide what needs to happen.

Indeed, a bit odd! I’ll open a case as you suggest. Kevin’s suggesting resolved this for me, but I think I should get an error if trying to set an index to a non-existent row and not a silent failure.

This is also a great example of how you can create a foot-gun when hacking out code. I started by writing the code to just fill in the control. Afterwards I added the If statement, but in the wrong place! Unfortunately, the most foot-guns have a silencer attached :grinning_face:

Thanks for the help!

Hi Ian!

I’m looping over an array to build the Popup Menu. Are you saying that it will not maintain the array index in the For loop? I like you’re suggestion to use the “SelectRowWithText”. Very neat!

Thanks!

Dermot

The documentation does not agree with me. It says that arrays are looped in index order. I’ve seen other places suggest the opposite. I just can’t find it anymore. Besides For To… next provides the counter for you with no extra code.

For Each didn’t guarantee the order for a very long time but this was corrected relatively recently, if memory serves.

I had thought that, but wasn’t sure. Thanks

Opened request #81772

Thanks again for your help!

Isn’t that the same issue as in https://tracker.xojo.com/xojoinc/xojo/-/issues/78108 ?

DesktopPopupMenu.SelectedRowIndex does not throw an OutOfBoundsException when the value is out of bounds

Thank you for pointing that out to me, Beatrix! I’ll conduct a more thorough search before opening a ticket in the future. I’ve closed out the ticket.

Cheers!!

Dermot