Multiple-selection Listbox contextual menu problem

I’m trying to implement something and so far having no luck. I have a listbox with “SelectionType” set to “Multiple,” and it works as expected. I would like to allow the user to right-click/control-click on the listbox to bring up a contextual menu while maintaining the current selection.

However, as soon as the user right- or control-clicks, the selection (potentially multiple rows), changes to a single selected row where the click was made.

If I put this code in the cellClick event handler:

if IsContextualClick then return true,
the selection remains when the user clicks, but, the “ConstructContextualMenu” event doesn’t fire.

What am I missing?

[quote=23797:@Peter Truskier]If I put this code in the cellClick event handler:

if IsContextualClick then return true

Put that code in the MouseDown event instead and it should work.

[quote=23797:@Peter Truskier]I’m trying to implement something and so far having no luck. I have a listbox with “SelectionType” set to “Multiple,” and it works as expected. I would like to allow the user to right-click/control-click on the listbox to bring up a contextual menu while maintaining the current selection.

However, as soon as the user right- or control-clicks, the selection (potentially multiple rows), changes to a single selected row where the click was made.

If I put this code in the cellClick event handler:

if IsContextualClick then return true,
the selection remains when the user clicks, but, the “ConstructContextualMenu” event doesn’t fire.

What am I missing?[/quote]

  1. First create a method to construct the contextual menu and pass in base. Say MakeContextMenu( Base as menuItem)
  2. Call that from the ConstructContextualMenu event:
  3. Create a method to to Handle the selection if needed… Call it DoContextAction(hitItem as menuItem)
  4. In MouseDown (not cellClick - user could click on empty part of the listbox and lose selection) Do

If NOT IsContextualClick then Return False Dim base as New menuItem MakeContextMenu(base) Dim hitItem as MenuItem = Base.Popup DoContextAction(hitItem) Return True

Sorry for resurrecting this old post, but I just followed this link through from https://forum.xojo.com/32053-windows-listbox-contextual-menu

Just in case someone else is trying to find the info, all you need to do is add the following code to your MouseDown on the ListBox:

if IsContextualClick AND me.Selected(me.RowFromXY(x, y)) then return True end if

This implements standard windows behaviour, if you right click on an existing selection, whether its a single entry or multiple entries then you bring up the menu. If you right click on an unselected entry, it will highlight that single selected entry and bring up the menu clearing any previous selections.

You can then use the standard events for ConstructContextualMenu and ContextMenuAction.

The only thing it doesn’t do, which it should, is move the highlighted row to the entry where the MouseDown was invoked when right clicking on multiple rows.

I’ve tried updating ListIndex then re-selecting the previously selected rows but that doesnt seem to do it, if anyone could shed some light on that, it would be apperciated.

[code] if IsContextualClick AND me.Selected(me.RowFromXY(x, y)) then

Dim selectedRows() As Integer

For row As Integer = 0 To me.ListCount - 1
  If me.Selected(row) Then
    selectedRows.Append row
  End If
Next

me.ListIndex = me.RowFromXY(x, y) ' this resets all selected entries to try and move the entry with a dotted line around

For row As Integer = 0 To me.ListCount - 1 ' restore previous state
  if selectedRows.Ubound > -1 then
    If row = selectedRows(0) then
      me.Selected(row) = True
      selectedRows.Remove(0)
    End If
  end if
Next

return True

end if[/code]

Did you try it with just:

[code] me.Selected(me.RowFromXY(x,y)) = True

if IsContextualClick then
return True
end if[/code]

[quote=264183:@Sascha S]Did you try it with just:

[code] me.Selected(me.RowFromXY(x,y)) = True

if IsContextualClick then
return True
end if[/code][/quote]
That breaks when you have a selection and right click on an unselected entry:

I just re-tested my code against a standard windows control and its working correctly, sorry for the confusion:

This is all you need in the ListBox’s MouseDown event:

if IsContextualClick AND me.Selected(me.RowFromXY(x, y)) then return True end if

Hope it helps someone.