Contextual Menu Implementation

I have listbox with multiple columns. I have a column for “Order Status”, “Order Type”, “Requested Ship Date”. When the user right clicks on the cell for each of these I want to build a contextual menu to allow the user to select from a list of values, based on the column and cell clicked. I want the contextual menu to be dynamic and related to the type of cell clicked (date, status, etc.), or “contextual”.

I noticed that the event ConstructContextualMenu does not pass the row and column which I could used to add the appropriate menu items (seems odd). I could define a property and store those on the CellClick event to use when contextual click occurs, but that seems a little messy. I could just define my own menu on the cell click event and do that instead of using ConstructContextualMenu.

This is on Windows 10.

Suggestions for best implementation or ideas?

something like this?


Function CellPressed(row As Integer, column As Integer, x As Integer, y As Integer) Handles CellPressed as Boolean
  If IsContextualClick Then
    Var m As New DesktopMenuItem
    m.AddMenu New DesktopMenuItem("Abc","Tag")
    Var item As DesktopMenuItem = m.PopUp
    If item<> Nil Then
      System.DebugLog item.Tag
      System.DebugLog Me.CellTextAt(row, column)
    End If
    Return True
  End If
End Function
1 Like

In h ConstructContextualMenu event you can use the X and Y value passed in to get the row and column using (API 1) Listbox.RowFromXY and Listbox.ColumnFrom XY…

That said it would have made sense fro Xojo to pass them in for a listbox … but I suspect they wanted to keep the even the same for all RectControls.

-Karen

2 Likes

Or they could implement a CellConstructContextualMenu(row, column) as Boolean and if not handled, raise the ConstructContextualMenu event. And they could then position the contextual menu adjacent to the cell, etc., etc. Which is basically what I did in my own code. There’s a menu for the cell, and if not handled, a menu for the listbox as a whole.

1 Like

I don’t see any problem in the ConstructContextualMenu you can write:

Var row As Integer=Me.RowFromXY(x, y)
Var column As Integer=Me.ColumnFromXY(x, y)
base.AddMenu New DesktopMenuItem(row.ToString+"; "+column.ToString)

they use the same x, y parameters for two reasons:consistency and you can need the x and/or y and row and column can be obtained easily.
BTW row is also me.selectedRowIndex

1 Like

All great suggestions. Thanks for everyone’s help.

Why do RowFromXY and ColumnFromXY take both x and y, by the way? A column doesn’t need the y parameter to be discovered and a row doesn’t need x either.
Always wondered… :thinking:

Because the underlying APIs calculate both at the same time.

Thanks.
This shifts the question to “why does the API calculate both?”. In the end, calculating a row won’t even involve the x axis and calculating a column never has to deal with the y axis.
Sounds silly to me… :man_shrugging:

Think about clicking on the header or a scroll bar . They are internal to the list box abd a header is not a row and a click on a scroll bar is not a click on a row or column.

You need both coordinates to get a correct result.

Because the underlying call is “get me the cell for this x and y”. Being able to get the column or row still requires both and it cannot be inferred.

Then a unique result as Pair could be a good solution to avoid the double call (if some one need both the values)

called Vector2D :slight_smile: (or Point)