我正在使用CefSharp作爲Gui的Winforms項目。出於幾個原因,我想使用Winforms的ContextMenu類實現一個自定義的上下文菜單;在Html中呈現菜單或自定義ChromiumWebBrowser的上下文菜單(使用CefSharp.IContextMenuHandler)不是一種選擇。通過ChromiumWebBrowser顯示Winforms Contextmenu
它通過調用.NET對象我傳遞給RegisterAsyncJsObject上的方法Javascript代碼觸發的上下文菜單;使用Javascript阻止了默認的上下文菜單。我在Gui線程上調用方法調用,因爲通過「javascript橋」調用註冊對象來自不同的線程。
我的問題:手動顯示Winforms上下文菜單通過CefSharp.WinForms.ChromiumWebBrowser時,上下文菜單不會獲得鍵盤焦點(例如,使用箭頭鍵選擇項目不起作用,也不能使用Esc關閉上下文菜單);相反,鍵盤焦點仍然與ChromiumWebBrowser控件保持一致。而且,如果我點擊ChromiumWebBrowser的控制區域,上下文菜單也不會關閉。我只能通過用鼠標選擇一個項目或者單擊窗體中的其他控件(包含ChromiumWebBrowser)或其他完全控制的其他控件(例如桌面或其他應用程序)來關閉上下文菜單。
如果我引發的右鍵菜單在我的代碼的其他地方 - 最終使用調用myContextMenu.Show同樣的方法() - 根據需要上下文菜單獲取鍵盤焦點。但有一個問題仍然存在:當我在ChromiumWebBrowser控件中單擊時,它不會關閉。
我沒有用過IFocusHander,IContextMenuHandler,IKeyboardHandler - 要這樣呢?
我使用CEF 3.2454.1344.g2782fb8,鉻45.0.2454.101和.net 4.5.1。
不幸的是提取演示代碼是不合理的。
任何任何想法?
EDIT1: 閱讀評論之後,我決定來形容碼流更確切地說:
- 當右擊的JavaScript將消息發送到已註冊的.NET對象,包含鼠標座標。通過在
ContextMenu
事件的MouseEvent參數上設置preventDefault
可以防止默認的上下文菜單。 - 註冊.NET對象接收消息並調用
windowForm.Invoke(Sub() ...)
,因爲主/ GUI線程上未接收到該消息,但必須有處理爲上下文菜單正確顯示。創建 - 的文本菜單和分配給包含實際ChromiumWebBrowser控制該用戶控件的
ContextMenuStrip
屬性。 - 它使用
ContextMenuStrip.Show(location)
方法顯示。
問題:
- 上下文菜單中沒有鍵盤焦點。
- 所有鼠標事件似乎被ChromiumWebBrowser「吞噬」:單擊那裏沒有關閉上下文菜單。
- 打開上下文菜單相同,除了使用不同的「觸發器」工作正常,除了第二個問題。
首先,默認是運行在它自己的線程的消息循環,導致在某些問題情景,如與菜單交互。還有一個選項,請參閱https://github.com/cefsharp/CefSharp/commit/fe11f2eada542f49e4eef0feed9b2b0978446bbf#diff-f142d024925e73816b0fabd620d2f71d瞭解一些粗略的細節。 從那開始,然後回報。我個人會考慮修改現有的上下文菜單,通過'IContextMenuHandler'添加,刪除命令。 – amaitland
作爲參考,可能需要提供一個工作示例,您的問題很複雜,並且根據您的工作情況稍做調整。 MinimalExample項目可以用作參考點。 https://github.com/cefsharp/CefSharp.MinimalExample很明顯,從改變消息循環開始,看看你能得到多少。 – amaitland
@amaitland:感謝您的反饋!使用'IContextMenuHandler'不是一個可行的解決方案,因爲上下文菜單使用了幾個自定義菜單項類(當應用程序是僅限Gdi時實現的),而且瀏覽器的上下文菜單看起來不同:我正在尋找一個無縫集成即用戶不應該注意到Gui實際上是Html。 – mike