I'm working on a Winforms project that uses CefSharp as a Gui. For several reasons I would like to implement a custom context menu using the Winforms ContextMenu class; rendering the menu in Html or customizing the ChromiumWebBrowser's context menu (using CefSharp.IContextMenuHandler) are not an option.
The context menu it triggered by Javascript code that calls a method on a .net object I passed to RegisterAsyncJsObject; the default context menu is prevented using Javascript. I'm invoking the method call on the Gui thread, because the call over the "javascript bridge" to the registered object comes from a different thread.
My problem: when manually showing the Winforms context menu over the CefSharp.WinForms.ChromiumWebBrowser the context menu does not get the keyboard focus (e.g. selecting items with the arrow key doesn't work nor can I close the contextmenu using Esc); instead the keyboard focus remains with the ChromiumWebBrowser control. And, if I click on the ChromiumWebBrowser's control area the context menu doesn't close either. I can only close the context menu by selecting an item with the mouse or clicking on another control within the form (in which the ChromiumWebBrowser is contained) or somewhere completely else (e.g. desktop or another application).
If I trigger the context menu from elsewhere in my code - ultimately using the same method that calls myContextMenu.Show() - the context menu gets the keyboard focus as desired. But one problem still remains: it doesn't close when I click within the ChromiumWebBrowser control.
I haven't used IFocusHander, IContextMenuHandler, IKeyboardHandler - should I?
I'm using CEF 3.2454.1344.g2782fb8, Chromium 45.0.2454.101 and .net 4.5.1.
Unfortunately extracting demo code isn't reasonably possible.
Anyone any ideas?
EDIT1: After reading the comments, I decided to describe the code flow more precisely:
- When right clicking Javascript sends a message to the registered .net object, containing the mouse coordinates. The default context menu is prevented by setting
preventDefault
on the MouseEvent arguments of theContextMenu
event. - The registered .net object receives the messages and calls
windowForm.Invoke(Sub() ... )
, because the message is not received on the Main/Gui thread, but must be processed there for the context menu to appear correctly. - The contextmenu is created and assigned to the
ContextMenuStrip
property of the UserControl that contains the actual ChromiumWebBrowser control. - It is displayed using
ContextMenuStrip.Show(location)
method.
Issues:
- The context menu has no keyboard-focus.
- All mouse events appear to be "swallowed" by the ChromiumWebBrowser: clicking there does not close the context menu.
- Opening the context menu identically except for using a different "trigger" works fine, except for the 2nd issue.