Set PopupMenu ListIndex

  1. 5 years ago

    In my (very simple) application, I have a popupmenu, that contains a short list of monthly bill descriptions like so :

    Broadband
    Council Tax
    Credit Card
    Home Insurance
    Utilities

    (There are others but I've shortened the list for the purpose of showing here).

    In the rowtag for each item above, I have added the primary key ID (Integer) from the SQLite table that contains the information. So building it up, it now looks like this:

    Rowtag       Text            Popupmenu Listindex
    ------       ----            -------------------
    8            Broadband       0
    4            Council Tax     1
    6            Credit Card     2
    9            Home Insurance  3
    3            Utilities       4

    Rowtag values then, are always unique but not always in numeric order, and will rarely, if ever, match the listindex value of the popupmenu.

    In the program, I also have a property called 'AccountID' which is set elsewhere when a particular account is selected, and contains the same primary key ID as described above.

    The idea with the code I'm about to show you is to set the listindex of the popupmenu to match the selected bill description, by comparing the rowtag to the AccountID.

    Going on the above information, if the user selects for example the 'Home Insurance' account elsewhere on the screen, the AccountID property is set to a value of 9.

    The code I have to do this is in a method as shown below :

    SetTransactionAccount(AccountID As Integer)
      For i As Integer = 0 To wMain.pmTransactionAccount.ListCount-1 ' zero based control, so start at 0 and subtract 1 from the total
        If wMain.pmTransactionAccount.RowTag(i)=AccountID Then       ' does the rowtag match the AccountID I'm interested in ?
          wMain.pmTransactionAccount.ListIndex = i                   ' if it matches, set the ListIndex based on the ListCount value
          Exit For i                                                 ' Exit the method since no further checks are required
        End If                                                       ' This comparison is finished
      Next                                                           ' Check the next ListCount item in the popupmenu

    The code above works; my 2 questions are:

    1. Is this the correct way to set the popupmenu listindex to match the selected account ?
    2. Is 'Exit For i' the correct way to gracefully exit the method, since we dont want to do any more checks once the first (And only) match is found ?
  2. Uncommented code (It didn't wrap as much when I typed the message) :

      For i As Integer = 0 To wMain.pmTransactionAccount.ListCount-1
        If wMain.pmTransactionAccount.RowTag(i)=AccountID Then
          wMain.pmTransactionAccount.ListIndex = i
          Exit For i
        End If
      Next
      
  3. Roger C

    6 Feb 2015 Lewis Center, OH

    That's essentially the way I handle similar situations.

  4. Markus W

    6 Feb 2015 #JeSuisHuman New Zealand, Auc...

    I do it in a similar way, except I have it as an extension method to the popup. That way I can just set it like

    myPopup.SetText( TextToDisplay )

    for any popup that needs it.

  5. Thanks guys, at least I know Im on the right track. Its worked so far 100% in every test.

    Markus, any chance you could share the way you did that? Im not familiar with extending that way just yet.

  6. Markus W

    7 Feb 2015 #JeSuisHuman New Zealand, Auc...

    From one xDev Tips&Tricks column:

    Whenever I see where a little effort could provide big rewards I want to see it implemented. As a beginner I stayed away from "advanced" stuff like Extends. But there is really nothing to it - it is simply a way to add a method or function to the build-in classes like shown in these two examples:

    Function Contains(Extends TextContainer as String, TextToFind as String) as Boolean return TextContainer.InStr( TextToFind ) > 0 End Function Function IsEmpty (Extends aString As String) as Boolean return theString = "" End Function

    Now writing

     if myText.contains("Xojo") then

    or

    if MyDocument.text.IsEmpty then


    certainly makes your code much easier to read and maintain than writing

     if InStr( myText, "Xojo") > 0 then

    or

     if MyDocument.text = "" then


    From another xDev Tips&Tricks column:

    If you are using PopupMenus then often you have to set the text of the PopupMenu to some value. The code is often like this:

    for i as integer = 0 to pm.ListCount-1
       if pm.list(i) = sSomeText then
          pm.ListIndex = i
          exit
       end
    next


    and after writing it a few times you might have put it into a method like me. However as Bob Keeney points out in his blog (http://www.bkeeneybriefs.com/2014/10/subclassing-vs-extends-vs-containers/ ) it is much nicer to do this as an extension:

    Sub SetText(extends pm as PopupMenu, assigns s as String)
       for i as integer = 0 to pm.ListCount-1
          if pm.list(i) = s then
             pm.ListIndex = i
             return  // exit
          end
       next
       // what if text is not in the popup menu?
       MsgBox "I tried to set <" + pm.Name + "> to <" + s + "> but it is not one of the available choices. Please inform the developer of this."
     End Sub


    This way it becomes part of the AutoComplete list and you simply call it like this:

    pmFont.setText = sSomeText


    What is this "assigns"? It means that we pass the string in with the "assignment operator" =. We could also have written the method declaration as

    Sub SetText(extends pm as PopupMenu, s as String)


    in which case we would call the function by passing an argument like this

    pmFont.setText( sSomeText )


    or without brackets like this

    pmFont.setText sSomeText


    But what if the text is not in the popup menu because you made a typo somewhere? In this case the popup menu will just stay as it is and not change to the new text. This is another one of those hard to find errors as no error is being raised. To account for that you could raise an error exception or just call a message box and put an error message up. Note that you need to change the exit from Bob's original tip to return, as exit only exits the loop while return exits the method.

  7. Edited 5 years ago

    Thankyou Markus, I'll look at this for my stuff.

    I see its come from an xDev article. Any idea how long that takes when you get the Omega Bundle ? I've had some of the licenses and stuff come through but not all of them yet.

  8. Markus W

    7 Feb 2015 #JeSuisHuman New Zealand, Auc...

    You should have it all within a few days (certainly the xDev). Don't forget to check your spam folder too!

    If you haven't gotten it after 3 or 4 days then maybe send Marc Zeedar an email

or Sign Up to reply!