简体   繁体   中英

.NET Is it possible to have a contextmenu on an item of a combobox?

In my application I have dropdown list with several items. I'd like to show a context menu when the user clicks the right mouse button on a dropdown item. Is this possible? And if it is possible, how?

It is possible but not easy. The ComboBox dropdown is a native ListBox that is created on-the-fly. To get the handle of that list box, you have to send the CB_GETCOMBOBOXINFO message in the DropDown event. Check my answer in this thread to find out how to do this.

The iceberg that is likely to sink that Titanic is that the dropdown automatically closes as soon as it loses focus. Which will happen as soon as you display the context menu. Nothing you can do about that.

Consider a different approach, you could use an actual ListBox that you make visible when the user clicks a glyph that looks like an arrow next a TextBox.

Not possible easily. No hover or right-click event messages are being sent when the combobox is expanded.

You can see this is the case when using Spy++.

I think the easiest would be to change to a listbox if your scenario allows you to do that.

As Wim said in his post, there's not a direct way to do this because the messages you want aren't fired.

As a comprise, you could try setting DropdownStyle=Simple; on the Combo and shrink the scroll region to show a single line:

http://img34.imageshack.us/img34/1695/49557147.jpg

If you assign the Combo a context menu, it will open when the scroll region is right-clicked. You'd probably have to figure out what item was right-clicked. But as other have said, this doesn't sound like a standard Windows way or an intuitive use.

Or how about a modal dialog that you could bring up from the Combo's context menu? On the dialog, you could have a list that the user could select from and a Delete button to delete the selected item(s).

For those asking "Why?" or saying they've never seen a combobox with a contextmenu; Look at any web browser's favorites dropdown. You can right click and delete, edit, or go to the entry in current tab, new tab, or new window. I also could not get an actual contextmenustrip to show, so I made a menu with a small borderless form and call with:

Private Sub FavoritesBar_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles FavoritesBar.SelectedIndexChanged
    FavIndex = FavoritesBar.SelectedIndex 'FavIndex is declared as a public string.
    Dim Loc As Point = New Point(MousePosition)
    FavMenu.Location = Loc
    FavMenu.ShowDialog()
End Sub

With a homemade contextmenu, be sure to add "me.close" at the end of each sub as well as the me.mouseleave event.

Since MenuItem doesn't have a ContextMenu property it isn't as easy as it is with many other controls. You'll probably need to capture the right-click event and then position and show the context menu manually.

Two caveats though:

  • The combobox list will close when the list loses focus, so it may close when the context menu is shown leaving the user unclear as to what they clicked on (not 100% sure on this, since I haven't written the code to test.)

  • More importantly though I would argue that this is a poor UI choice, I can't think of any real world applications I've used that have context menus on menu items, so it wouldn't be very discoverable for the end user. Plus context menus should be just for quick access, they shouldn't be the only way to access functionality. Are you going to be able to expose these functions through other means as well as the right-click menu?

You could do it manually, by capturing the event on the form, but consider making a nested menu instead. If your combobox items have menus of their own, combobox probably isn't the right choice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM